5.15.168-rc1 review
Greg Kroah-Hartman
maintainerPATCH 420/691 wifi: ath11k: fix array out-of-bound access in SoC stats
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karthikeyan Periyasamy <[email protected]>
[ Upstream commit 69f253e46af98af17e3efa3e5dfa72fcb7d1983d ]
Currently, the ath11k_soc_dp_stats::hal_reo_error array is defined with a maximum size of DP_REO_DST_RING_MAX. However, the ath11k_dp_process_rx() function access ath11k_soc_dp_stats::hal_reo_error using the REO destination SRNG ring ID, which is incorrect. SRNG ring ID differ from normal ring ID, and this usage leads to out-of-bounds array access. To fix this issue, modify ath11k_dp_process_rx() to use the normal ring ID directly instead of the SRNG ring ID to avoid out-of-bounds array access.
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath11k/dp_rx.c +1 -1
@@ -2637,7 +2637,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,if (push_reason !=HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION ) {dev_kfree_skb_any (msdu); - ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++; + ab->soc_stats.hal_reo_error[ring_id]++;continue ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 421/691 wifi: rtw88: select WANT_DEV_COREDUMP
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zong-Zhe Yang <[email protected]>
[ Upstream commit 7e989b0c1e33210c07340bf5228aa83ea52515b5 ]
We have invoked device coredump when fw crash.
Should select WANT_DEV_COREDUMP by ourselves.
--- drivers/net/wireless/realtek/rtw88/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/realtek/rtw88/Kconfig +1 -0
@@ -12,6 +12,7 @@ if RTW88 config RTW88_CORE tristate + select WANT_DEV_COREDUMP config RTW88_PCI tristate
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 422/691 ACPI: EC: Do not release locks during operation region accesses
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit dc171114926ec390ab90f46534545420ec03e458 ]
It is not particularly useful to release locks (the EC mutex and the ACPI global lock, if present) and re-acquire them immediately thereafter during EC address space accesses in acpi_ec_space_handler().
First, releasing them for a while before grabbing them again does not really help anyone because there may not be enough time for another thread to acquire them.
Second, if another thread successfully acquires them and carries out a new EC write or read in the middle if an operation region access in progress, it may confuse the EC firmware, especially after the burst mode has been enabled.
Finally, manipulating the locks after writing or reading every single byte of data is overhead that it is better to avoid.
Accordingly, modify the code to carry out EC address space accesses entirely without releasing the locks.
--- drivers/acpi/ec.c | 55 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-)
drivers/acpi/ec.c +49 -6
@@ -773,6 +773,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,unsigned long tmp;int ret =0 ; +if (t->rdata) +memset (t->rdata,0 , t->rlen); +/* start transaction */ spin_lock_irqsave (&ec->lock, tmp);/* Enable GPE for command processing (IBF=0/OBF=1) */
@@ -809,8 +812,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))return -EINVAL ; -if (t->rdata) -memset (t->rdata,0 , t->rlen);mutex_lock (&ec->mutex);if (ec->global_lock) {
@@ -837,7 +838,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) .wdata = NULL, .rdata = &d, .wlen = 0, .rlen = 1}; -return acpi_ec_transaction (ec, &t); +return acpi_ec_transaction_unlocked (ec, &t); }static int acpi_ec_burst_disable (struct acpi_ec *ec)
@@ -847,7 +848,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) .wlen = 0, .rlen = 0};return (acpi_ec_read_status (ec) &ACPI_EC_FLAG_BURST ) ? -acpi_ec_transaction (ec, &t) :0 ; +acpi_ec_transaction_unlocked (ec, &t) :0 ; }static int acpi_ec_read (struct acpi_ec *ec,u8 address,u8 *data)
@@ -863,6 +864,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)return result; } +static int acpi_ec_read_unlocked (struct acpi_ec *ec,u8 address,u8 *data) +{ +int result; +u8 d; +struct transaction t = {.command =ACPI_EC_COMMAND_READ , + .wdata = &address, .rdata = &d, + .wlen =1 , .rlen =1 }; + + result =acpi_ec_transaction_unlocked (ec, &t); + *data = d; +return result; +} +static int acpi_ec_write (struct acpi_ec *ec,u8 address,u8 data) {u8 wdata[2 ] = { address, data };
@@ -873,6 +887,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)return acpi_ec_transaction (ec, &t); } +static int acpi_ec_write_unlocked (struct acpi_ec *ec,u8 address,u8 data) +{ +u8 wdata[2 ] = { address, data }; +struct transaction t = {.command =ACPI_EC_COMMAND_WRITE , + .wdata = wdata, .rdata =NULL , + .wlen =2 , .rlen =0 }; + +return acpi_ec_transaction_unlocked (ec, &t); +} +int ec_read (u8 addr,u8 *val) {int err;
@@ -1293,6 +1317,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,struct acpi_ec *ec = handler_context;int result =0 , i, bytes = bits /8 ;u8 *value = (u8 *)value64; +u32 glk;if ((address >0xFF ) || !value || !handler_context)return AE_BAD_PARAMETER ;
@@ -1300,13 +1325,25 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,if (function !=ACPI_READ && function !=ACPI_WRITE )return AE_BAD_PARAMETER ; +mutex_lock (&ec->mutex); + +if (ec->global_lock) { +acpi_status status; + + status =acpi_acquire_global_lock (ACPI_EC_UDELAY_GLK , &glk); +if (ACPI_FAILURE (status)) { + result = -ENODEV ; + goto unlock; + } + } +if (ec->busy_polling || bits >8 )acpi_ec_burst_enable (ec);for (i =0 ; i < bytes; ++i, ++address, ++value) { result = (function ==ACPI_READ ) ? -acpi_ec_read (ec, address, value) : -acpi_ec_write (ec, address, *value); +acpi_ec_read_unlocked (ec, address, value) : +acpi_ec_write_unlocked (ec, address, *value);if (result <0 )break ; }
@@ -1314,6 +1351,12 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,if (ec->busy_polling || bits >8 )acpi_ec_burst_disable (ec); +if (ec->global_lock) +acpi_release_global_lock (glk); + +unlock: +mutex_unlock (&ec->mutex); +switch (result) {case -EINVAL :return AE_BAD_PARAMETER ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 423/691 ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in acpi_db_convert_to_package()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pei Xiao <[email protected]>
[ Upstream commit a5242874488eba2b9062985bf13743c029821330 ]
ACPICA commit 4d4547cf13cca820ff7e0f859ba83e1a610b9fd0
ACPI_ALLOCATE_ZEROED() may fail, elements might be NULL and will cause NULL pointer dereference later.
--- drivers/acpi/acpica/dbconvert.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/acpi/acpica/dbconvert.c +2 -0
@@ -174,6 +174,8 @@ acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object) elements =ACPI_ALLOCATE_ZEROED (DB_DEFAULT_PKG_ELEMENTS *sizeof (union acpi_object )); +if (!elements) +return (AE_NO_MEMORY ); this = string;for (i =0 ; i < (DB_DEFAULT_PKG_ELEMENTS -1 ); i++) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 424/691 tipc: guard against string buffer overrun
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Horman <[email protected]>
[ Upstream commit 6555a2a9212be6983d2319d65276484f7c5f431a ]
Smatch reports that copying media_name and if_name to name_parts may overwrite the destination.
.../bearer.c:166 bearer_name_validate() error: strcpy() 'media_name' too large for 'name_parts->media_name' (32 vs 16) .../bearer.c:167 bearer_name_validate() error: strcpy() 'if_name' too large for 'name_parts->if_name' (1010102 vs 16)
This does seem to be the case so guard against this possibility by using strscpy() and failing if truncation occurs.
Introduced by commit b97bf3fd8f6a ("[TIPC] Initial merge")
Compile tested only.
--- net/tipc/bearer.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/tipc/bearer.c +6 -2
@@ -163,8 +163,12 @@ static int bearer_name_validate(const char *name,/* return bearer name components, if necessary */ if (name_parts) { -strcpy (name_parts->media_name, media_name); -strcpy (name_parts->if_name, if_name); +if (strscpy (name_parts->media_name, media_name, +TIPC_MAX_MEDIA_NAME ) <0 ) +return 0 ; +if (strscpy (name_parts->if_name, if_name, +TIPC_MAX_IF_NAME ) <0 ) +return 0 ; }return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 425/691 net: mvpp2: Increase size of queue_name buffer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Horman <[email protected]>
[ Upstream commit 91d516d4de48532d967a77967834e00c8c53dfe6 ]
Increase size of queue_name buffer from 30 to 31 to accommodate the largest string written to it. This avoids truncation in the possibly unlikely case where the string is name is the maximum size.
Flagged by gcc-14:
.../mvpp2_main.c: In function 'mvpp2_probe':
.../mvpp2_main.c:7636:32: warning: 'snprintf' output may be truncated before the last format character [-Wformat-truncation=]
7636 | "stats-wq-%s%s", netdev_name(priv->port_list[0]->dev),
| ^
.../mvpp2_main.c:7635:9: note: 'snprintf' output between 10 and 31 bytes into a destination of size 30
7635 | snprintf(priv->queue_name, sizeof(priv->queue_name),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7636 | "stats-wq-%s%s", netdev_name(priv->port_list[0]->dev),
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7637 | priv->port_count > 1 ? "+" : "");
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Introduced by commit 118d6298f6f0 ("net: mvpp2: add ethtool GOP statistics"). I am not flagging this as a bug as I am not aware that it is one.
Compile tested only.
--- drivers/net/ethernet/marvell/mvpp2/mvpp2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2.h +1 -1
@@ -1088,7 +1088,7 @@ struct mvpp2 {unsigned int max_port_rxqs;/* Workqueue to gather hardware statistics */ -char queue_name[30 ]; +char queue_name[31 ];struct workqueue_struct *stats_queue;/* Debugfs root entry */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 426/691 ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR).
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit e3af3d3c5b26c33a7950e34e137584f6056c4319 ]
dev->ip_ptr could be NULL if we set an invalid MTU.
Even then, if we issue ioctl(SIOCSIFADDR) for a new IPv4 address, devinet_ioctl() allocates struct in_ifaddr and fails later in inet_set_ifa() because in_dev is NULL.
Let's move the check earlier.
--- net/ipv4/devinet.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
net/ipv4/devinet.c +2 -4
@@ -566,10 +566,6 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)ASSERT_RTNL (); -if (!in_dev) { -inet_free_ifa (ifa); -return -ENOBUFS ; - }ipv4_devconf_setall (in_dev);neigh_parms_data_state_setall (in_dev->arp_parms);if (ifa->ifa_dev != in_dev) {
@@ -1149,6 +1145,8 @@ int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)if (!ifa) { ret = -ENOBUFS ; +if (!in_dev) +break ; ifa =inet_alloc_ifa ();if (!ifa)break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 427/691 ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 8fed54758cd248cd311a2b5c1e180abef1866237 ]
The NETLINK_FIB_LOOKUP netlink family can be used to perform a FIB lookup according to user provided parameters and communicate the result back to user space.
However, unlike other users of the FIB lookup API, the upper DSCP bits and the ECN bits of the DS field are not masked, which can result in the wrong result being returned.
Solve this by masking the upper DSCP bits and the ECN bits using IPTOS_RT_MASK.
The structure that communicates the request and the response is not exported to user space, so it is unlikely that this netlink family is actually in use [1].
[1] https://lore.kernel.org/netdev/ZpqpB8vJU%2FQ6LSqa@debian/
--- net/ipv4/fib_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/fib_frontend.c +1 -1
@@ -1332,7 +1332,7 @@ static void nl_fib_lookup(struct net *net, struct fib_result_nl *frn)struct flowi4 fl4 = { .flowi4_mark = frn->fl_mark, .daddr = frn->fl_addr, - .flowi4_tos = frn->fl_tos, + .flowi4_tos = frn->fl_tos &IPTOS_RT_MASK , .flowi4_scope = frn->fl_scope, };struct fib_table *tb;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 428/691 net: atlantic: Avoid warning about potential string truncation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Horman <[email protected]>
[ Upstream commit 5874e0c9f25661c2faefe4809907166defae3d7f ]
W=1 builds with GCC 14.2.0 warn that:
.../aq_ethtool.c:278:59: warning: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 6 [-Wformat-truncation=]
278 | snprintf(tc_string, 8, "TC%d ", tc);
| ^~.../aq_ethtool.c:278:56: note: directive argument in the range [-2147483641, 254]
278 | snprintf(tc_string, 8, "TC%d ", tc);
| ^~~~~~~.../aq_ethtool.c:278:33: note: ‘snprintf’ output between 5 and 15 bytes into a destination of size 8
278 | snprintf(tc_string, 8, "TC%d ", tc);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tc is always in the range 0 - cfg->tcs. And as cfg->tcs is a u8, the range is 0 - 255. Further, on inspecting the code, it seems that cfg->tcs will never be more than AQ_CFG_TCS_MAX (8), so the range is actually 0 - 8.
So, it seems that the condition that GCC flags will not occur. But, nonetheless, it would be nice if it didn't emit the warning.
It seems that this can be achieved by changing the format specifier from %d to %u, in which case I believe GCC recognises an upper bound on the range of tc of 0 - 255. After some experimentation I think this is due to the combination of the use of %u and the type of cfg->tcs (u8).
Empirically, updating the type of the tc variable to unsigned int has the same effect.
As both of these changes seem to make sense in relation to what the code is actually doing - iterating over unsigned values - do both.
Compile tested only.
--- drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +2 -2
@@ -256,7 +256,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,const int rx_stat_cnt =ARRAY_SIZE (aq_ethtool_queue_rx_stat_names);const int tx_stat_cnt =ARRAY_SIZE (aq_ethtool_queue_tx_stat_names);char tc_string[8 ]; -int tc; +unsigned int tc;memset (tc_string,0 ,sizeof (tc_string)); memcpy(p, aq_ethtool_stat_names,
@@ -265,7 +265,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,for (tc =0 ; tc < cfg->tcs; tc++) {if (cfg->is_qos) -snprintf (tc_string,8 ,"TC%d " , tc); +snprintf (tc_string,8 ,"TC%u " , tc);for (i =0 ; i < cfg->vecs; i++) {for (si =0 ; si < rx_stat_cnt; si++) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 429/691 tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Xing <[email protected]>
[ Upstream commit 0d9e5df4a257afc3a471a82961ace9a22b88295a ]
We found that one close-wait socket was reset by the other side due to a new connection reusing the same port which is beyond our expectation, so we have to investigate the underlying reason.
The following experiment is conducted in the test environment. We limit the port range from 40000 to 40010 and delay the time to close() after receiving a fin from the active close side, which can help us easily reproduce like what happened in production.
Here are three connections captured by tcpdump:
127.0.0.1.40002 > 127.0.0.1.9999: Flags [S], seq 2965525191 127.0.0.1.9999 > 127.0.0.1.40002: Flags [S.], seq 2769915070 127.0.0.1.40002 > 127.0.0.1.9999: Flags [.], ack 1 127.0.0.1.40002 > 127.0.0.1.9999: Flags [F.], seq 1, ack 1 // a few seconds later, within 60 seconds 127.0.0.1.40002 > 127.0.0.1.9999: Flags [S], seq 2965590730 127.0.0.1.9999 > 127.0.0.1.40002: Flags [.], ack 2 127.0.0.1.40002 > 127.0.0.1.9999: Flags [R], seq 2965525193 // later, very quickly
127.0.0.1.40002 > 127.0.0.1.9999: Flags [S], seq 2965590730 127.0.0.1.9999 > 127.0.0.1.40002: Flags [S.], seq 3120990805 127.0.0.1.40002 > 127.0.0.1.9999: Flags [.], ack 1
As we can see, the first flow is reset because:
1) client starts a new connection, I mean, the second one
2) client tries to find a suitable port which is a timewait socket (its state is timewait, substate is fin_wait2)
3) client occupies that timewait port to send a SYN
4) server finds a corresponding close-wait socket in ehash table, then replies with a challenge ack
5) client sends an RST to terminate this old close-wait socket.
I don't think the port selection algo can choose a FIN_WAIT2 socket when we turn on tcp_tw_reuse because on the server side there remain unread data. In some cases, if one side haven't call close() yet, we should not consider it as expendable and treat it at will.
Even though, sometimes, the server isn't able to call close() as soon as possible like what we expect, it can not be terminated easily, especially due to a second unrelated connection happening.
After this patch, we can see the expected failure if we start a connection when all the ports are occupied in fin_wait2 state:
"Ncat: Cannot assign requested address."
--- net/ipv4/tcp_ipv4.c | 3 +++ 1 file changed, 3 insertions(+)
net/ipv4/tcp_ipv4.c +3 -0
@@ -113,6 +113,9 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)const struct tcp_timewait_sock *tcptw =tcp_twsk (sktw);struct tcp_sock *tp =tcp_sk (sk); +if (tw->tw_substate ==TCP_FIN_WAIT2 ) + reuse =0 ; +if (reuse ==2 ) {/* Still does not detect *everything* that goes through * lo, since we require a loopback src or dst address
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 430/691 ACPICA: iasl: handle empty connection_node
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandrs Vinarskis <[email protected]>
[ Upstream commit a0a2459b79414584af6c46dd8c6f866d8f1aa421 ]
ACPICA commit 6c551e2c9487067d4b085333e7fe97e965a11625
--- drivers/acpi/acpica/exprep.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/acpi/acpica/exprep.c +3 -0
@@ -437,6 +437,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)if (info->connection_node) { second_desc = info->connection_node->object; +if (second_desc ==NULL ) { +break ; + }if (!(second_desc->common.flags &AOPOBJ_DATA_VALID )) { status =acpi_ds_get_buffer_arguments (second_desc);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 431/691 proc: add config & param to block forcing mem writes
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Ratiu <[email protected]>
[ Upstream commit 41e8149c8892ed1962bd15350b3c3e6e90cba7f4 ]
This adds a Kconfig option and boot param to allow removing the FOLL_FORCE flag from /proc/pid/mem write calls because it can be abused.
The traditional forcing behavior is kept as default because it can break GDB and some other use cases.
Previously we tried a more sophisticated approach allowing distributions to fine-tune /proc/pid/mem behavior, however that got NAK-ed by Linus [1], who prefers this simpler approach with semantics also easier to understand for users.
--- .../admin-guide/kernel-parameters.txt | 10 +++ fs/proc/base.c | 61 ++++++++++++++++++- security/Kconfig | 32 ++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-)
Documentation/admin-guide/kernel-parameters.txt +10 -0
@@ -4333,6 +4333,16 @@ printk.time= Show timing data prefixed to each printk message line Format: <bool> (1/Y/y=enable, 0/N/n=disable) + proc_mem.force_override= [KNL] + Format: {always | ptrace | never} + Traditionally /proc/pid/mem allows memory permissions to be + overridden without restrictions. This option may be set to + restrict that. Can be one of: + - 'always': traditional behavior always allows mem overrides. + - 'ptrace': only allow mem overrides for active ptracers. + - 'never': never allow mem overrides. + If not specified, default is the CONFIG_PROC_MEM_* choice. + processor.max_cstate= [HW,ACPI] Limit processor to maximum C-state max_cstate=9 overrides any DMI blacklist limit.
fs/proc/base.c +60 -1
85 lines not on this page · raw message
security/Kconfig +32 -0
@@ -19,6 +19,38 @@ config SECURITY_DMESG_RESTRICT If you are unsure how to answer this question, answer N. +choice + prompt "Allow /proc/pid/mem access override" + default PROC_MEM_ALWAYS_FORCE + help + Traditionally /proc/pid/mem allows users to override memory + permissions for users like ptrace, assuming they have ptrace + capability. + + This allows people to limit that - either never override, or + require actual active ptrace attachment. + + Defaults to the traditional behavior (for now) + +config PROC_MEM_ALWAYS_FORCE + bool "Traditional /proc/pid/mem behavior" + help + This allows /proc/pid/mem accesses to override memory mapping + permissions if you have ptrace access rights. + +config PROC_MEM_FORCE_PTRACE + bool "Require active ptrace() use for access override" + help + This allows /proc/pid/mem accesses to override memory mapping + permissions for active ptracers like gdb. + +config PROC_MEM_NO_FORCE + bool "Never" + help + Never override memory mapping permissions + +endchoice + config SECURITY bool "Enable different security models" depends on SYSFS
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 432/691 wifi: mt76: mt7915: hold dev->mt76.mutex while disabling tx worker
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
[ Upstream commit 8f7152f10cb434f954aeff85ca1be9cd4d01912b ]
Prevent racing against other functions disabling the same worker
--- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +3 -1
@@ -1653,13 +1653,15 @@ void mt7915_mac_reset_work(struct work_struct *work)set_bit (MT76_RESET , &phy2->mt76->state);cancel_delayed_work_sync (&phy2->mt76->mac_work); } + +mutex_lock (&dev->mt76.mutex); +mt76_worker_disable (&dev->mt76.tx_worker);napi_disable (&dev->mt76.napi[0 ]);napi_disable (&dev->mt76.napi[1 ]);napi_disable (&dev->mt76.napi[2 ]);napi_disable (&dev->mt76.tx_napi); -mutex_lock (&dev->mt76.mutex);mt76_wr (dev,MT_MCU_INT_EVENT ,MT_MCU_INT_EVENT_DMA_STOPPED );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 433/691 wifi: mwifiex: Fix memcpy() field-spanning write warning in mwifiex_cmd_802_11_scan_ext()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva <[email protected]>
[ Upstream commit 498365e52bebcbc36a93279fe7e9d6aec8479cee ]
Replace one-element array with a flexible-array member in struct host_cmd_ds_802_11_scan_ext.
With this, fix the following warning:
elo 16 17:51:58 surfacebook kernel: ------------[ cut here ]------------
elo 16 17:51:58 surfacebook kernel: memcpy: detected field-spanning write (size 243) of single field "ext_scan->tlv_buffer" at drivers/net/wireless/marvell/mwifiex/scan.c:2239 (size 1) elo 16 17:51:58 surfacebook kernel: WARNING: CPU: 0 PID: 498 at drivers/net/wireless/marvell/mwifiex/scan.c:2239 mwifiex_cmd_802_11_scan_ext+0x83/0x90 [mwifiex]
--- drivers/net/wireless/marvell/mwifiex/fw.h | 2 +- drivers/net/wireless/marvell/mwifiex/scan.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-)
drivers/net/wireless/marvell/mwifiex/fw.h +1 -1
@@ -1598,7 +1598,7 @@ struct host_cmd_ds_802_11_scan_rsp {struct host_cmd_ds_802_11_scan_ext {u32 reserved; -u8 tlv_buffer[1 ]; +u8 tlv_buffer[]; } __packed;struct mwifiex_ie_types_bss_mode {
drivers/net/wireless/marvell/mwifiex/scan.c +1 -2
@@ -2560,8 +2560,7 @@ int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv, ext_scan_resp = &resp->params.ext_scan; tlv = (void *)ext_scan_resp->tlv_buffer; - buf_left =le16_to_cpu (resp->size) - (sizeof (*ext_scan_resp) +S_DS_GEN - -1 ); + buf_left =le16_to_cpu (resp->size) - (sizeof (*ext_scan_resp) +S_DS_GEN );while (buf_left >=sizeof (struct mwifiex_ie_types_header )) { type =le16_to_cpu (tlv->type);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 434/691 nfp: Use IRQF_NO_AUTOEN flag in request_irq()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit daaba19d357f0900b303a530ced96c78086267ea ]
disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ.
--- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/netronome/nfp/nfp_net_common.c +2 -3
@@ -2665,8 +2665,8 @@ nfp_net_prepare_vector(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,snprintf (r_vec->name,sizeof (r_vec->name),"%s-rxtx-%d" ,nfp_net_name (nn), idx); - err =request_irq (r_vec->irq_vector, r_vec->handler,0 , r_vec->name, - r_vec); + err =request_irq (r_vec->irq_vector, r_vec->handler,IRQF_NO_AUTOEN , + r_vec->name, r_vec);if (err) {if (nn->dp.netdev)netif_napi_del (&r_vec->napi);
@@ -2676,7 +2676,6 @@ nfp_net_prepare_vector(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,nn_err (nn,"Error requesting IRQ %d\n" , r_vec->irq_vector);return err; } -disable_irq (r_vec->irq_vector);irq_set_affinity_hint (r_vec->irq_vector, &r_vec->affinity_mask);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 435/691 signal: Replace BUG_ON()s
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 7f8af7bac5380f2d95a63a6f19964e22437166e1 ]
These really can be handled gracefully without killing the machine.
--- kernel/signal.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
kernel/signal.c +7 -4
@@ -1932,10 +1932,11 @@ struct sigqueue *sigqueue_alloc(void)void sigqueue_free (struct sigqueue *q) { -unsigned long flags;spinlock_t *lock = ¤t->sighand->siglock; +unsigned long flags; -BUG_ON (!(q->flags &SIGQUEUE_PREALLOC )); +if (WARN_ON_ONCE (!(q->flags &SIGQUEUE_PREALLOC ))) +return ;/* * We must hold ->siglock while testing q->list * to serialize with collect_signal() or with
@@ -1963,7 +1964,10 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)unsigned long flags;int ret, result; -BUG_ON (!(q->flags &SIGQUEUE_PREALLOC )); +if (WARN_ON_ONCE (!(q->flags &SIGQUEUE_PREALLOC ))) +return 0 ; +if (WARN_ON_ONCE (q->info.si_code !=SI_TIMER )) +return 0 ; ret =-1 ;rcu_read_lock ();
@@ -1982,7 +1986,6 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)* If an SI_TIMER entry is already queue just increment * the overrun count. */ -BUG_ON (q->info.si_code !=SI_TIMER ); q->info.si_overrun++; result =TRACE_SIGNAL_ALREADY_PENDING ; goto out;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 436/691 ALSA: usb-audio: Add input value sanity checks for standard types
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 901e85677ec0bb9a69fb9eab1feafe0c4eb7d07e ]
For an invalid input value that is out of the given range, currently USB-audio driver corrects the value silently and accepts without errors. This is no wrong behavior, per se, but the recent kselftest rather wants to have an error in such a case, hence a different behavior is expected now.
This patch adds a sanity check at each control put for the standard mixer types and returns an error if an invalid value is given.
Note that this covers only the standard mixer types. The mixer quirks that have own control callbacks would need different coverage.
--- sound/usb/mixer.c | 35 +++++++++++++++++++++++++++-------- sound/usb/mixer.h | 1 + 2 files changed, 28 insertions(+), 8 deletions(-)
sound/usb/mixer.c +27 -8
@@ -1346,6 +1346,19 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,#define get_min_max (cval, def) get_min_max_with_quirks(cval, def, NULL) +/* get the max value advertised via control API */ +static int get_max_exposed (struct usb_mixer_elem_info *cval) +{ +if (!cval->max_exposed) { +if (cval->res) + cval->max_exposed = +DIV_ROUND_UP (cval->max - cval->min, cval->res); +else + cval->max_exposed = cval->max - cval->min; + } +return cval->max_exposed; +} +/* get a feature/mixer unit info */ static int mixer_ctl_feature_info (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_info *uinfo)
@@ -1358,11 +1371,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,else uinfo->type =SNDRV_CTL_ELEM_TYPE_INTEGER ; uinfo->count = cval->channels; -if (cval->val_type ==USB_MIXER_BOOLEAN || - cval->val_type ==USB_MIXER_INV_BOOLEAN ) { - uinfo->value.integer.min =0 ; - uinfo->value.integer.max =1 ; - }else { +if (cval->val_type !=USB_MIXER_BOOLEAN && + cval->val_type !=USB_MIXER_INV_BOOLEAN ) {if (!cval->initialized) {get_min_max_with_quirks (cval,0 , kcontrol);if (cval->initialized && cval->dBmin >= cval->dBmax) {
@@ -1374,10 +1384,10 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, &kcontrol->id); } } - uinfo->value.integer.min =0 ; - uinfo->value.integer.max = -DIV_ROUND_UP (cval->max - cval->min, cval->res); } + + uinfo->value.integer.min =0 ; + uinfo->value.integer.max =get_max_exposed (cval);return 0 ; }
@@ -1418,6 +1428,7 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {struct usb_mixer_elem_info *cval = kcontrol->private_data; +int max_val =get_max_exposed (cval);int c, cnt, val, oval, err;int changed =0 ;
@@ -1430,6 +1441,8 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.integer.value[cnt]; +if (val <0 || val > max_val) +return -EINVAL ; val =get_abs_value (cval, val);if (oval != val) {snd_usb_set_cur_mix_value (cval, c +1 , cnt, val);
@@ -1443,6 +1456,8 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.integer.value[0 ]; +if (val <0 || val > max_val) +return -EINVAL ; val =get_abs_value (cval, val);if (val != oval) {snd_usb_set_cur_mix_value (cval,0 ,0 , val);
@@ -2301,6 +2316,8 @@ static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.integer.value[0 ]; +if (val <0 || val >get_max_exposed (cval)) +return -EINVAL ; val =get_abs_value (cval, val);if (val != oval) {set_cur_ctl_value (cval, cval->control <<8 , val);
@@ -2663,6 +2680,8 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,if (err <0 )return filter_error (cval, err); val = ucontrol->value.enumerated.item[0 ]; +if (val <0 || val >= cval->max)/* here cval->max = # elements */ +return -EINVAL ; val =get_abs_value (cval, val);if (val != oval) {set_cur_ctl_value (cval, cval->control <<8 , val);
sound/usb/mixer.h +1 -0
@@ -88,6 +88,7 @@ struct usb_mixer_elem_info {int channels;int val_type;int min, max, res; +int max_exposed;/* control API exposes the value in 0..max_exposed */ int dBmin, dBmax;int cached;int cache_val[MAX_CHANNELS ];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 437/691 x86/ioapic: Handle allocation failures gracefully
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 830802a0fea8fb39d3dc9fb7d6b5581e1343eb1f ]
Breno observed panics when using failslab under certain conditions during runtime:
can not alloc irq_pin_list (-1,0,20)
Kernel panic - not syncing: IO-APIC: failed to add irq-pin. Can not proceed panic+0x4e9/0x590 mp_irqdomain_alloc+0x9ab/0xa80 irq_domain_alloc_irqs_locked+0x25d/0x8d0 __irq_domain_alloc_irqs+0x80/0x110 mp_map_pin_to_irq+0x645/0x890 acpi_register_gsi_ioapic+0xe6/0x150 hpet_open+0x313/0x480
That's a pointless panic which is a leftover of the historic IO/APIC code which panic'ed during early boot when the interrupt allocation failed.
The only place which might justify panic is the PIT/HPET timer_check() code which tries to figure out whether the timer interrupt is delivered through the IO/APIC. But that code does not require to handle interrupt allocation failures. If the interrupt cannot be allocated then timer delivery fails and it either panics due to that or falls back to legacy mode.
Cure this by removing the panic wrapper around __add_pin_to_irq_node() and making mp_irqdomain_alloc() aware of the failure condition and handle it as any other failure in this function gracefully.
--- arch/x86/kernel/apic/io_apic.c | 46 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-)
arch/x86/kernel/apic/io_apic.c +22 -24
@@ -350,27 +350,26 @@ static void ioapic_mask_entry(int apic, int pin)* shared ISA-space IRQs, so we have to support them. We are super * fast in the common case, and fast for shared ISA-space IRQs. */ -static int __add_pin_to_irq_node (struct mp_chip_data *data, -int node,int apic,int pin) +static bool add_pin_to_irq_node (struct mp_chip_data *data,int node,int apic,int pin) {struct irq_pin_list *entry; -/* don't allow duplicates */ -for_each_irq_pin (entry, data->irq_2_pin) +/* Don't allow duplicates */ +for_each_irq_pin (entry, data->irq_2_pin) {if (entry->apic == apic && entry->pin == pin) -return 0 ; +return true; + } entry =kzalloc_node (sizeof (struct irq_pin_list ),GFP_ATOMIC , node);if (!entry) { -pr_err ("can not alloc irq_pin_list (%d,%d,%d)\n" , - node, apic, pin); -return -ENOMEM ; +pr_err ("Cannot allocate irq_pin_list (%d,%d,%d)\n" , node, apic, pin); +return false; } + entry->apic = apic; entry->pin = pin;list_add_tail (&entry->list, &data->irq_2_pin); - -return 0 ; +return true; }static void __remove_pin_from_irq (struct mp_chip_data *data,int apic,int pin)
@@ -385,13 +384,6 @@ static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin) } } -static void add_pin_to_irq_node (struct mp_chip_data *data, -int node,int apic,int pin) -{ -if (__add_pin_to_irq_node (data, node, apic, pin)) -panic ("IO-APIC: failed to add irq-pin. Can not proceed\n" ); -} -/* * Reroute an IRQ to a different pin. */
@@ -1000,8 +992,7 @@ static int alloc_isa_irq_from_domain(struct irq_domain *domain,if (irq_data && irq_data->parent_data) {if (!mp_check_pin_attr (irq, info))return -EBUSY ; -if (__add_pin_to_irq_node (irq_data->chip_data, node, ioapic, - info->ioapic.pin)) +if (!add_pin_to_irq_node (irq_data->chip_data, node, ioapic, info->ioapic.pin))return -ENOMEM ; }else { info->flags |=X86_IRQ_ALLOC_LEGACY ;
@@ -3024,10 +3015,8 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,return -ENOMEM ; ret =irq_domain_alloc_irqs_parent (domain, virq, nr_irqs, info); -if (ret <0 ) { -kfree (data); -return ret; - } +if (ret <0 ) + goto free_data;INIT_LIST_HEAD (&data->irq_2_pin); irq_data->hwirq = info->ioapic.pin;
@@ -3036,7 +3025,10 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, irq_data->chip_data = data;mp_irqdomain_get_attr (mp_pin_to_gsi (ioapic, pin), data, info); -add_pin_to_irq_node (data,ioapic_alloc_attr_node (info), ioapic, pin); +if (!add_pin_to_irq_node (data,ioapic_alloc_attr_node (info), ioapic, pin)) { + ret = -ENOMEM ; + goto free_irqs; + }mp_preconfigure_entry (data);mp_register_handler (virq, data->is_level);
@@ -3051,6 +3043,12 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, ioapic,mpc_ioapic_id (ioapic), pin, virq, data->is_level, data->active_low);return 0 ; + +free_irqs: +irq_domain_free_irqs_parent (domain, virq, nr_irqs); +free_data: +kfree (data); +return ret; } void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 438/691 ALSA: usb-audio: Define macros for quirk table entries
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 0c3ad39b791c2ecf718afcaca30e5ceafa939d5c ]
Many entries in the USB-audio quirk tables have relatively complex expressions. For improving the readability, introduce a few macros. Those are applied in the following patch.
--- sound/usb/quirks-table.h | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
sound/usb/quirks-table.h +77 -0
@@ -35,6 +35,83 @@ .bInterfaceClass = USB_CLASS_AUDIO, \ .bInterfaceSubClass =USB_SUBCLASS_AUDIOCONTROL +/* Quirk .driver_info, followed by the definition of the quirk entry; +* put like QUIRK_DRIVER_INFO { ... } in each entry of the quirk table + */ +#define QUIRK_DRIVER_INFO \ + .driver_info = (unsigned long)&(const struct snd_usb_audio_quirk) + +/* +* Macros for quirk data entries +*/ + +/* Quirk data entry for ignoring the interface */ +#define QUIRK_DATA_IGNORE (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_IGNORE_INTERFACE +/* Quirk data entry for a standard audio interface */ +#define QUIRK_DATA_STANDARD_AUDIO (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_AUDIO_STANDARD_INTERFACE +/* Quirk data entry for a standard MIDI interface */ +#define QUIRK_DATA_STANDARD_MIDI (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_MIDI_STANDARD_INTERFACE +/* Quirk data entry for a standard mixer interface */ +#define QUIRK_DATA_STANDARD_MIXER (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_AUDIO_STANDARD_MIXER + +/* Quirk data entry for Yamaha MIDI */ +#define QUIRK_DATA_MIDI_YAMAHA (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_MIDI_YAMAHA +/* Quirk data entry for Edirol UAxx */ +#define QUIRK_DATA_EDIROL_UAXX (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_AUDIO_EDIROL_UAXX +/* Quirk data entry for raw bytes interface */ +#define QUIRK_DATA_RAW_BYTES (_ifno) \ + .ifnum = (_ifno), .type = QUIRK_MIDI_RAW_BYTES + +/* Quirk composite array terminator */ +#define QUIRK_COMPOSITE_END { .ifnum = -1 } + +/* Quirk data entry for composite quirks; +* followed by the quirk array that is terminated with QUIRK_COMPOSITE_END +* e.g. QUIRK_DATA_COMPOSITE { { quirk1 }, { quirk2 },..., QUIRK_COMPOSITE_END } +*/ +#define QUIRK_DATA_COMPOSITE \ + .ifnum = QUIRK_ANY_INTERFACE, \ + .type = QUIRK_COMPOSITE, \ + .data = &(const struct snd_usb_audio_quirk[]) + +/* Quirk data entry for a fixed audio endpoint; +* followed by audioformat definition +* e.g. QUIRK_DATA_AUDIOFORMAT(n) { .formats = xxx, ... } +*/ +#define QUIRK_DATA_AUDIOFORMAT (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_AUDIO_FIXED_ENDPOINT, \ + .data = &(const struct audioformat) + +/* Quirk data entry for a fixed MIDI endpoint; +* followed by snd_usb_midi_endpoint_info definition +* e.g. QUIRK_DATA_MIDI_FIXED_ENDPOINT(n) { .out_cables = x, .in_cables = y } +*/ +#define QUIRK_DATA_MIDI_FIXED_ENDPOINT (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_MIDI_FIXED_ENDPOINT, \ + .data = &(const struct snd_usb_midi_endpoint_info) +/* Quirk data entry for a MIDIMAN MIDI endpoint */ +#define QUIRK_DATA_MIDI_MIDIMAN (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_MIDI_MIDIMAN, \ + .data = &(const struct snd_usb_midi_endpoint_info) +/* Quirk data entry for a EMAGIC MIDI endpoint */ +#define QUIRK_DATA_MIDI_EMAGIC (_ifno) \ + .ifnum = (_ifno), \ + .type = QUIRK_MIDI_EMAGIC, \ + .data = &(const struct snd_usb_midi_endpoint_info) + +/* +* Here we go... the quirk table definition begins: +*/ +/* FTDI devices */ { USB_DEVICE(0x0403, 0xb8d8),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 439/691 ALSA: usb-audio: Add logitech Audio profile quirk
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Pius <[email protected]>
[ Upstream commit a51c925c11d7b855167e64b63eb4378e5adfc11d ]
Specify shortnames for the following Logitech Devices: Rally bar, Rally bar mini, Tap, MeetUp and Huddle.
--- sound/usb/card.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/usb/card.c +6 -0
@@ -382,6 +382,12 @@ static const struct usb_audio_device_name usb_audio_names[] = {/* Creative/Toshiba Multimedia Center SB-0500 */ DEVICE_NAME (0x041e ,0x3048 ,"Toshiba" ,"SB-0500" ), +/* Logitech Audio Devices */ +DEVICE_NAME (0x046d ,0x0867 ,"Logitech, Inc." ,"Logi-MeetUp" ), +DEVICE_NAME (0x046d ,0x0874 ,"Logitech, Inc." ,"Logi-Tap-Audio" ), +DEVICE_NAME (0x046d ,0x087c ,"Logitech, Inc." ,"Logi-Huddle" ), +DEVICE_NAME (0x046d ,0x0898 ,"Logitech, Inc." ,"Logi-RB-Audio" ), +DEVICE_NAME (0x046d ,0x08d2 ,"Logitech, Inc." ,"Logi-RBM-Audio" ),DEVICE_NAME (0x046d ,0x0990 ,"Logitech, Inc." ,"QuickCam Pro 9000" ), DEVICE_NAME(0x05e1, 0x0408, "Syntek", "STK1160"),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 440/691 tools/x86/kcpuid: Protect against faulty "max subleaf" values
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmed S. Darwish <[email protected]>
[ Upstream commit cf96ab1a966b87b09fdd9e8cc8357d2d00776a3a ]
Protect against the kcpuid code parsing faulty max subleaf numbers through a min() expression. Thus, ensuring that max_subleaf will always be ≤ MAX_SUBLEAF_NUM.
Use "u32" for the subleaf numbers since kcpuid is compiled with -Wextra, which includes signed/unsigned comparisons warnings.
--- tools/arch/x86/kcpuid/kcpuid.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
tools/arch/x86/kcpuid/kcpuid.c +5 -7
@@ -7,7 +7,8 @@#include <string.h> #include <getopt.h> -#define ARRAY_SIZE (x) (sizeof(x) / sizeof((x)[0])) +#define ARRAY_SIZE (x) (sizeof(x) / sizeof((x)[0])) +#define min (a, b) (((a) < (b)) ? (a) : (b))typedef unsigned int u32 ;typedef unsigned long long u64 ;
@@ -203,12 +204,9 @@ static void raw_dump_range(struct cpuid_range *range)#define MAX_SUBLEAF_NUM 32struct cpuid_range *setup_cpuid_range (u32 input_eax) { -u32 max_func, idx_func; -int subleaf; +u32 max_func, idx_func, subleaf, max_subleaf; +u32 eax, ebx, ecx, edx, f = input_eax;struct cpuid_range *range; -u32 eax, ebx, ecx, edx; -u32 f = input_eax; -int max_subleaf;bool allzero; eax = input_eax;
@@ -254,7 +252,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)* others have to be tried (0xf) */ if (f ==0x7 || f ==0x14 || f ==0x17 || f ==0x18 ) - max_subleaf = (eax &0xff ) +1 ; + max_subleaf =min ((eax &0xff ) +1 , max_subleaf);if (f ==0xb ) max_subleaf =2 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 441/691 ALSA: asihpi: Fix potential OOB array access
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 7b986c7430a6bb68d523dac7bfc74cbd5b44ef96 ]
ASIHPI driver stores some values in the static array upon a response from the driver, and its index depends on the firmware. We shouldn't trust it blindly.
This patch adds a sanity check of the array index to fit in the array size.
--- sound/pci/asihpi/hpimsgx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/asihpi/hpimsgx.c +1 -1
@@ -713,7 +713,7 @@ static u16 HPIMSGX__init(struct hpi_message *phm, phr->error =HPI_ERROR_PROCESSING_MESSAGE ;return phr->error; } -if (hr.error ==0 ) { +if (hr.error ==0 && hr.u.s.adapter_index <HPI_MAX_ADAPTERS ) {/* the adapter was created successfully save the mapping for future use */ hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 442/691 ALSA: hdsp: Break infinite MIDI input flush loop
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit c01f3815453e2d5f699ccd8c8c1f93a5b8669e59 ]
The current MIDI input flush on HDSP and HDSPM drivers relies on the hardware reporting the right value. If the hardware doesn't give the proper value but returns -1, it may be stuck at an infinite loop.
Add a counter and break if the loop is unexpectedly too long.
--- sound/pci/rme9652/hdsp.c | 6 ++++-- sound/pci/rme9652/hdspm.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-)
sound/pci/rme9652/hdsp.c +4 -2
@@ -1298,8 +1298,10 @@ static int snd_hdsp_midi_output_possible (struct hdsp *hdsp, int id)static void snd_hdsp_flush_midi_input (struct hdsp *hdsp,int id) { -while (snd_hdsp_midi_input_available (hdsp, id)) -snd_hdsp_midi_read_byte (hdsp, id); +int count =256 ; + +while (snd_hdsp_midi_input_available (hdsp, id) && --count) +snd_hdsp_midi_read_byte (hdsp, id); }static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
sound/pci/rme9652/hdspm.c +4 -2
@@ -1838,8 +1838,10 @@ static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)static void snd_hdspm_flush_midi_input (struct hdspm *hdspm,int id) { -while (snd_hdspm_midi_input_available (hdspm, id)) -snd_hdspm_midi_read_byte (hdspm, id); +int count =256 ; + +while (snd_hdspm_midi_input_available (hdspm, id) && --count) +snd_hdspm_midi_read_byte (hdspm, id); }static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 443/691 x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit d19d638b1e6cf746263ef60b7d0dee0204d8216a ]
Modern (fortified) memcpy() prefers to avoid writing (or reading) beyond the end of the addressed destination (or source) struct member:
In function ‘fortify_memcpy_chk’,
inlined from ‘syscall_get_arguments’ at ./arch/x86/include/asm/syscall.h:85:2,
inlined from ‘populate_seccomp_data’ at kernel/seccomp.c:258:2,
inlined from ‘__seccomp_filter’ at kernel/seccomp.c:1231:3:./include/linux/fortify-string.h:580:25: error: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror=attribute-warning]
580 | __read_overflow2_field(q_size_field, size);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~As already done for x86_64 and compat mode, do not use memcpy() to extract syscall arguments from struct pt_regs but rather just perform direct assignments. Binary output differences are negligible, and actually ends up using less stack space:
- sub $0x84,%esp + sub $0x6c,%esp
and less text size:
text data bss dec hex filename
10794 252 0 11046 2b26 gcc-32b/kernel/seccomp.o.stock 10714 252 0 10966 2ad6 gcc-32b/kernel/seccomp.o.after
--- arch/x86/include/asm/syscall.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
arch/x86/include/asm/syscall.h +6 -1
@@ -82,7 +82,12 @@ static inline void syscall_get_arguments(struct task_struct *task,struct pt_regs *regs, unsigned long *args) { - memcpy(args, ®s->bx, 6 * sizeof(args[0])); + args[0 ] = regs->bx; + args[1 ] = regs->cx; + args[2 ] = regs->dx; + args[3 ] = regs->si; + args[4 ] = regs->di; + args[5 ] = regs->bp; } static inline void syscall_set_arguments(struct task_struct *task,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 444/691 fbdev: pxafb: Fix possible use after free in pxafb_task()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaixin Wang <[email protected]>
[ Upstream commit 4a6921095eb04a900e0000da83d9475eb958e61e ]
In the pxafb_probe function, it calls the pxafb_init_fbinfo function, after which &fbi->task is associated with pxafb_task. Moreover, within this pxafb_init_fbinfo function, the pxafb_blank function within the &pxafb_ops struct is capable of scheduling work.
If we remove the module which will call pxafb_remove to make cleanup, it will call unregister_framebuffer function which can call do_unregister_framebuffer to free fbi->fb through put_fb_info(fb_info), while the work mentioned above will be used. The sequence of operations that may lead to a UAF bug is as follows:
CPU0 CPU1
| pxafb_task
pxafb_remove |
unregister_framebuffer(info) |
do_unregister_framebuffer(fb_info) |
put_fb_info(fb_info) |
// free fbi->fb | set_ctrlr_state(fbi, state)
| __pxafb_lcd_power(fbi, 0)
| fbi->lcd_power(on, &fbi->fb.var)
| //use fbi->fbFix it by ensuring that the work is canceled before proceeding with the cleanup in pxafb_remove.
Note that only root user can remove the driver at runtime.
--- drivers/video/fbdev/pxafb.c | 1 + 1 file changed, 1 insertion(+)
drivers/video/fbdev/pxafb.c +1 -0
@@ -2408,6 +2408,7 @@ static int pxafb_remove(struct platform_device *dev) info = &fbi->fb;pxafb_overlay_exit (fbi); +cancel_work_sync (&fbi->task);unregister_framebuffer (info);pxafb_disable_controller (fbi);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 445/691 rcuscale: Provide clear error when async specified without primitives
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul E. McKenney <[email protected]>
[ Upstream commit 11377947b5861fa59bf77c827e1dd7c081842cc9 ]
Currently, if the rcuscale module's async module parameter is specified for RCU implementations that do not have async primitives such as RCU Tasks Rude (which now lacks a call_rcu_tasks_rude() function), there will be a series of splats due to calls to a NULL pointer. This commit therefore warns of this situation, but switches to non-async testing.
--- kernel/rcu/rcuscale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/rcu/rcuscale.c +2 -2
@@ -428,7 +428,7 @@ rcu_scale_writer(void *arg)udelay (writer_holdoff); wdp = &wdpp[i]; *wdp =ktime_get_mono_fast_ns (); -if (gp_async) { +if (gp_async && !WARN_ON_ONCE (!cur_ops->async)) { retry:if (!rhp) rhp =kmalloc (sizeof (*rhp),GFP_KERNEL );
@@ -484,7 +484,7 @@ rcu_scale_writer(void *arg) i++;rcu_scale_wait_shutdown (); }while (!torture_must_stop ()); -if (gp_async) { +if (gp_async && cur_ops->async) { cur_ops->gp_barrier (); } writer_n_durations[me] = i_max +1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 446/691 iommu/arm-smmu-qcom: hide last LPASS SMMU context bank from linux
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Gonzalez <[email protected]>
[ Upstream commit 3a8990b8a778219327c5f8ecf10b5d81377b925a ]
On qcom msm8998, writing to the last context bank of lpass_q6_smmu (base address 0x05100000) produces a system freeze & reboot.
The hardware/hypervisor reports 13 context banks for the LPASS SMMU on msm8998, but only the first 12 are accessible... Override the number of context banks
[ 2.546101] arm-smmu 5100000.iommu: probing hardware configuration... [ 2.552439] arm-smmu 5100000.iommu: SMMUv2 with: [ 2.558945] arm-smmu 5100000.iommu: stage 1 translation [ 2.563627] arm-smmu 5100000.iommu: address translation ops [ 2.568923] arm-smmu 5100000.iommu: non-coherent table walk [ 2.574566] arm-smmu 5100000.iommu: (IDR0.CTTW overridden by FW configuration) [ 2.580220] arm-smmu 5100000.iommu: stream matching with 12 register groups [ 2.587263] arm-smmu 5100000.iommu: 13 context banks (0 stage-2 only) [ 2.614447] arm-smmu 5100000.iommu: Supported page sizes: 0x63315000 [ 2.621358] arm-smmu 5100000.iommu: Stage-1: 36-bit VA -> 36-bit IPA [ 2.627772] arm-smmu 5100000.iommu: preserved 0 boot mappings
Specifically, the crashes occur here:
qsmmu->bypass_cbndx = smmu->num_context_banks - 1; arm_smmu_cb_write(smmu, qsmmu->bypass_cbndx, ARM_SMMU_CB_SCTLR, 0);
and here:
arm_smmu_write_context_bank(smmu, i); arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, ARM_SMMU_CB_FSR_FAULT);
It is likely that FW reserves the last context bank for its own use, thus a simple work-around is: DON'T USE IT in Linux.
If we decrease the number of context banks, last one will be "hidden".
--- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +7 -0
@@ -254,6 +254,13 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)u32 smr;int i; +/* +* MSM8998 LPASS SMMU reports 13 context banks, but accessing +* the last context bank crashes the system. +*/ +if (of_device_is_compatible (smmu->dev->of_node,"qcom,msm8998-smmu-v2" ) && smmu->num_context_banks ==13 ) + smmu->num_context_banks =12 ; +/* * Some platforms support more than the Arm SMMU architected maximum of * 128 stream matching groups. For unknown reasons, the additional
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 447/691 power: reset: brcmstb: Do not go into infinite loop if reset fails
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Davis <[email protected]>
[ Upstream commit cf8c39b00e982fa506b16f9d76657838c09150cb ]
There may be other backup reset methods available, do not halt here so that other reset methods can be tried.
--- drivers/power/reset/brcmstb-reboot.c | 3 --- 1 file changed, 3 deletions(-)
drivers/power/reset/brcmstb-reboot.c +0 -3
@@ -72,9 +72,6 @@ static int brcmstb_restart_handler(struct notifier_block *this,return NOTIFY_DONE ; } -while (1 ) - ; -return NOTIFY_DONE ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 448/691 iommu/vt-d: Always reserve a domain ID for identity setup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Baolu <[email protected]>
[ Upstream commit 2c13012e09190174614fd6901857a1b8c199e17d ]
We will use a global static identity domain. Reserve a static domain ID for it.
--- drivers/iommu/intel/iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iommu/intel/iommu.c +3 -3
@@ -1846,10 +1846,10 @@ static int iommu_init_domains(struct intel_iommu *iommu)* entry for first-level or pass-through translation modes should * be programmed with a domain id different from those used for * second-level or nested translation. We reserve a domain id for -* this purpose. +* this purpose. This domain id is also used for identity domain +* in legacy mode. */ -if (sm_supported (iommu)) -set_bit (FLPT_DEFAULT_DID , iommu->domain_ids); +set_bit (FLPT_DEFAULT_DID , iommu->domain_ids);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 449/691 iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanjay K Kumar <[email protected]>
[ Upstream commit 3cf74230c139f208b7fb313ae0054386eee31a81 ]
If qi_submit_sync() is invoked with 0 invalidation descriptors (for instance, for DMA draining purposes), we can run into a bug where a submitting thread fails to detect the completion of invalidation_wait. Subsequently, this led to a soft lockup. Currently, there is no impact by this bug on the existing users because no callers are submitting invalidations with 0 descriptors. This fix will enable future users (such as DMA drain) calling qi_submit_sync() with 0 count.
Suppose thread T1 invokes qi_submit_sync() with non-zero descriptors, while concurrently, thread T2 calls qi_submit_sync() with zero descriptors. Both threads then enter a while loop, waiting for their respective descriptors to complete. T1 detects its completion (i.e., T1's invalidation_wait status changes to QI_DONE by HW) and proceeds to call reclaim_free_desc() to reclaim all descriptors, potentially including adjacent ones of other threads that are also marked as QI_DONE.
During this time, while T2 is waiting to acquire the qi->q_lock, the IOMMU hardware may complete the invalidation for T2, setting its status to QI_DONE. However, if T1's execution of reclaim_free_desc() frees T2's invalidation_wait descriptor and changes its status to QI_FREE, T2 will not observe the QI_DONE status for its invalidation_wait and will indefinitely remain stuck.
This soft lockup does not occur when only non-zero descriptors are submitted.In such cases, invalidation descriptors are interspersed among wait descriptors with the status QI_IN_USE, acting as barriers. These barriers prevent the reclaim code from mistakenly freeing descriptors belonging to other submitters.
Considered the following example timeline:
T1 T2 ======================================== ID1 WD1 while(WD1!=QI_DONE) unlock lock WD1=QI_DONE* WD2 while(WD2!=QI_DONE) unlock lock WD1==QI_DONE? ID1=QI_DONE WD2=DONE* reclaim() ID1=FREE WD1=FREE WD2=FREE unlock soft lockup! T2 never sees QI_DONE in WD2
Where:
ID = invalidation descriptor
WD = wait descriptor
* Written by hardware
The root of the problem is that the descriptor status QI_DONE flag is used for two conflicting purposes:
1. signal a descriptor is ready for reclaim (to be freed)
2. signal by the hardware that a wait descriptor is complete
The solution (in this patch) is state separation by using QI_FREE flag for #1.
Once a thread's invalidation descriptors are complete, their status would be set to QI_FREE. The reclaim_free_desc() function would then only free descriptors marked as QI_FREE instead of those marked as QI_DONE. This change ensures that T2 (from the previous example) will correctly observe the completion of its invalidation_wait (marked as QI_DONE).
--- drivers/iommu/intel/dmar.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/iommu/intel/dmar.c +11 -5
@@ -1198,9 +1198,7 @@ static void free_iommu(struct intel_iommu *iommu)*/ static inline void reclaim_free_desc (struct q_inval *qi) { -while (qi->desc_status[qi->free_tail] ==QI_DONE || - qi->desc_status[qi->free_tail] ==QI_ABORT ) { - qi->desc_status[qi->free_tail] =QI_FREE ; +while (qi->desc_status[qi->free_tail] ==QI_FREE && qi->free_tail != qi->free_head) { qi->free_tail = (qi->free_tail +1 ) %QI_LENGTH ; qi->free_cnt++; }
@@ -1435,8 +1433,16 @@ int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc,raw_spin_lock (&qi->q_lock); } -for (i =0 ; i < count; i++) - qi->desc_status[(index + i) %QI_LENGTH ] =QI_DONE ; +/* +* The reclaim code can free descriptors from multiple submissions +* starting from the tail of the queue. When count == 0, the +* status of the standalone wait descriptor at the tail of the queue +* must be set to QI_FREE to allow the reclaim code to proceed. +* It is also possible that descriptors from one of the previous +* submissions has to be reclaimed by a subsequent submission. +*/ +for (i =0 ; i <= count; i++) + qi->desc_status[(index + i) %QI_LENGTH ] =QI_FREE ;reclaim_free_desc (qi);raw_spin_unlock_irqrestore (&qi->q_lock, flags);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 450/691 drm/amd/display: Add null check for top_pipe_to_program in commit_planes_for_stream
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit 66d71a72539e173a9b00ca0b1852cbaa5f5bf1ad ]
This commit addresses a null pointer dereference issue in the commit_planes_for_stream function at line 4140. The issue could occur when top_pipe_to_program is null.
The fix adds a check to ensure top_pipe_to_program is not null before accessing its stream_res. This prevents a null pointer dereference.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c:4140 commit_planes_for_stream() error: we previously assumed 'top_pipe_to_program' could be null (see line 3906)
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +2 -1
@@ -3027,7 +3027,8 @@ static void commit_planes_for_stream(struct dc *dc, dc->hwss.pipe_control_lock (dc, top_pipe_to_program, false);if ((update_type !=UPDATE_TYPE_FAST ) && stream->update_flags.bits.dsc_changed) -if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { +if (top_pipe_to_program && + top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { top_pipe_to_program->stream_res.tg->funcs->wait_for_state ( top_pipe_to_program->stream_res.tg,CRTC_STATE_VACTIVE );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 451/691 ata: sata_sil: Rename sil_blacklist to sil_quirks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit 93b0f9e11ce511353c65b7f924cf5f95bd9c3aba ]
Rename the array sil_blacklist to sil_quirks as this name is more neutral and is also consistent with how this driver define quirks with the SIL_QUIRK_XXX flags.
--- drivers/ata/sata_sil.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/ata/sata_sil.c +6 -6
@@ -128,7 +128,7 @@ static const struct pci_device_id sil_pci_tbl[] = {static const struct sil_drivelist {const char *product;unsigned int quirk; -} sil_blacklist [] = { +} sil_quirks[] = { {"ST320012AS" ,SIL_QUIRK_MOD15WRITE }, {"ST330013AS" ,SIL_QUIRK_MOD15WRITE }, {"ST340017AS" ,SIL_QUIRK_MOD15WRITE },
@@ -601,8 +601,8 @@ static void sil_thaw(struct ata_port *ap)* list, and apply the fixups to only the specific * devices/hosts/firmwares that need it. * -* 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted -* The Maxtor quirk is in the blacklist, but I'm keeping the original +* 20040111 - Seagate drives affected by the Mod15Write bug are quirked +* The Maxtor quirk is in sil_quirks, but I'm keeping the original * pessimistic fix for the following reasons... * - There seems to be less info on it, only one device gleaned off the * Windows driver, maybe only one is affected. More info would be greatly
@@ -621,9 +621,9 @@ static void sil_dev_config(struct ata_device *dev)ata_id_c_string (dev->id, model_num,ATA_ID_PROD ,sizeof (model_num)); -for (n =0 ; sil_blacklist[n].product; n++) -if (!strcmp (sil_blacklist[n].product, model_num)) { - quirks = sil_blacklist[n].quirk; +for (n =0 ; sil_quirks[n].product; n++) +if (!strcmp (sil_quirks[n].product, model_num)) { + quirks = sil_quirks[n].quirk;break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 452/691 drm/amd/display: Check null pointers before using dc->clk_mgr
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 95d9e0803e51d5a24276b7643b244c7477daf463 ]
[WHY & HOW]dc->clk_mgr is null checked previously in the same function, indicating it might be null.
Passing "dc" to "dc->hwss.apply_idle_power_optimizations", which dereferences null "dc->clk_mgr". (The function pointer resolves to "dcn35_apply_idle_power_optimizations".)
This fixes 1 FORWARD_NULL issue reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +2 -1
@@ -3671,7 +3671,8 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)if (allow == dc->idle_optimizations_allowed)return ; -if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations (dc, allow)) +if (dc->hwss.apply_idle_power_optimizations && dc->clk_mgr !=NULL && + dc->hwss.apply_idle_power_optimizations (dc, allow)) dc->idle_optimizations_allowed = allow; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 453/691 jfs: UBSAN: shift-out-of-bounds in dbFindBits
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Remington Brasga <[email protected]>
[ Upstream commit b0b2fc815e514221f01384f39fbfbff65d897e1c ]
Fix issue with UBSAN throwing shift-out-of-bounds warning.
--- fs/jfs/jfs_dmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jfs/jfs_dmap.c +1 -1
@@ -3088,7 +3088,7 @@ static int dbFindBits(u32 word, int l2nb)/* scan the word for nb free bits at nb alignments. */ -for (bitno =0 ; mask !=0 ; bitno += nb, mask >>= nb) { +for (bitno =0 ; mask !=0 ; bitno += nb, mask = (mask >> nb)) {if ((mask & word) == mask)break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 454/691 jfs: Fix uaf in dbFreeBits
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
[ Upstream commit d6c1b3599b2feb5c7291f5ac3a36e5fa7cedb234 ]
[syzbot reported]
==================================================================
BUG: KASAN: slab-use-after-free in __mutex_lock_common kernel/locking/mutex.c:587 [inline] BUG: KASAN: slab-use-after-free in __mutex_lock+0xfe/0xd70 kernel/locking/mutex.c:752 Read of size 8 at addr ffff8880229254b0 by task syz-executor357/5216 CPU: 0 UID: 0 PID: 5216 Comm: syz-executor357 Not tainted 6.11.0-rc3-syzkaller-00156-gd7a5aa4b3c00 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/27/2024 Call Trace: <TASK> __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 __mutex_lock_common kernel/locking/mutex.c:587 [inline] __mutex_lock+0xfe/0xd70 kernel/locking/mutex.c:752 dbFreeBits+0x7ea/0xd90 fs/jfs/jfs_dmap.c:2390 dbFreeDmap fs/jfs/jfs_dmap.c:2089 [inline] dbFree+0x35b/0x680 fs/jfs/jfs_dmap.c:409 dbDiscardAG+0x8a9/0xa20 fs/jfs/jfs_dmap.c:1650 jfs_ioc_trim+0x433/0x670 fs/jfs/jfs_discard.c:100 jfs_ioctl+0x2d0/0x3e0 fs/jfs/ioctl.c:131 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 Freed by task 5218: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579 poison_slab_object+0xe0/0x150 mm/kasan/common.c:240 __kasan_slab_free+0x37/0x60 mm/kasan/common.c:256 kasan_slab_free include/linux/kasan.h:184 [inline] slab_free_hook mm/slub.c:2252 [inline] slab_free mm/slub.c:4473 [inline] kfree+0x149/0x360 mm/slub.c:4594 dbUnmount+0x11d/0x190 fs/jfs/jfs_dmap.c:278 jfs_mount_rw+0x4ac/0x6a0 fs/jfs/jfs_mount.c:247 jfs_remount+0x3d1/0x6b0 fs/jfs/super.c:454 reconfigure_super+0x445/0x880 fs/super.c:1083 vfs_cmd_reconfigure fs/fsopen.c:263 [inline] vfs_fsconfig_locked fs/fsopen.c:292 [inline] __do_sys_fsconfig fs/fsopen.c:473 [inline] __se_sys_fsconfig+0xb6e/0xf80 fs/fsopen.c:345 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
[Analysis]
There are two paths (dbUnmount and jfs_ioc_trim) that generate race condition when accessing bmap, which leads to the occurrence of uaf.
Use the lock s_umount to synchronize them, in order to avoid uaf caused by race condition.
--- fs/jfs/jfs_discard.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
fs/jfs/jfs_discard.c +9 -2
@@ -65,7 +65,7 @@ void jfs_issue_discard(struct inode *ip, u64 blkno, u64 nblocks)int jfs_ioc_trim (struct inode *ip,struct fstrim_range *range) {struct inode *ipbmap =JFS_SBI (ip->i_sb)->ipbmap; -struct bmap *bmp =JFS_SBI (ip->i_sb)->bmap; +struct bmap *bmp;struct super_block *sb = ipbmap->i_sb;int agno, agno_end;u64 start, end, minlen;
@@ -83,10 +83,15 @@ int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range)if (minlen ==0 ) minlen =1 ; +down_read (&sb->s_umount); + bmp =JFS_SBI (ip->i_sb)->bmap; +if (minlen > bmp->db_agsize || start >= bmp->db_mapsize || - range->len < sb->s_blocksize) + range->len < sb->s_blocksize) { +up_read (&sb->s_umount);return -EINVAL ; + }if (end >= bmp->db_mapsize) end = bmp->db_mapsize -1 ;
@@ -100,6 +105,8 @@ int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range) trimmed +=dbDiscardAG (ip, agno, minlen); agno++; } + +up_read (&sb->s_umount); range->len = trimmed << sb->s_blocksize_bits;return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 455/691 jfs: check if leafidx greater than num leaves per dmap tree
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
[ Upstream commit d64ff0d2306713ff084d4b09f84ed1a8c75ecc32 ]
syzbot report a out of bounds in dbSplit, it because dmt_leafidx greater than num leaves per dmap tree, add a checking for dmt_leafidx in dbFindLeaf.
Shaggy:
Modified sanity check to apply to control pages as well as leaf pages.
--- fs/jfs/jfs_dmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/jfs/jfs_dmap.c +4 -1
@@ -3010,9 +3010,10 @@ static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl)static int dbFindLeaf (dmtree_t *tp,int l2nb,int *leafidx,bool is_ctl) {int ti, n =0 , k, x =0 ; -int max_size; +int max_size, max_idx; max_size = is_ctl ?CTLTREESIZE :TREESIZE ; + max_idx = is_ctl ?LPERCTL :LPERDMAP ;/* first check the root of the tree to see if there is * sufficient free space.
@@ -3044,6 +3045,8 @@ static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)*/ assert (n <4 ); } +if (le32_to_cpu (tp->dmt_leafidx) >= max_idx) +return -ENOSPC ;/* set the return to the leftmost leaf describing sufficient * free space.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 456/691 scsi: smartpqi: correct stream detection
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mahesh Rajashekhara <[email protected]>
[ Upstream commit 4c76114932d1d6fad2e72823e7898a3c960cf2a7 ]
Correct stream detection by initializing the structure pqi_scsi_dev_raid_map_data to 0s.
When the OS issues SCSI READ commands, the driver erroneously considers them as SCSI WRITES. If they are identified as sequential IOs, the driver then submits those requests via the RAID path instead of the AIO path.
The 'is_write' flag might be set for SCSI READ commands also. The driver may interpret SCSI READ commands as SCSI WRITE commands, resulting in IOs being submitted through the RAID path.
Note: This does not cause data corruption.
--- drivers/scsi/smartpqi/smartpqi_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/smartpqi/smartpqi_init.c +1 -1
@@ -5646,7 +5646,7 @@ static bool pqi_is_parity_write_stream(struct pqi_ctrl_info *ctrl_info,int rc;struct pqi_scsi_dev *device;struct pqi_stream_data *pqi_stream_data; -struct pqi_scsi_dev_raid_map_data rmd; +struct pqi_scsi_dev_raid_map_data rmd = {0 };if (!ctrl_info->enable_stream_detection)return false;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 457/691 jfs: Fix uninit-value access of new_ea in ea_buffer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Mengmeng <[email protected]>
[ Upstream commit 2b59ffad47db1c46af25ccad157bb3b25147c35c ]
syzbot reports that lzo1x_1_do_compress is using uninit-value:
=====================================================
BUG: KMSAN: uninit-value in lzo1x_1_do_compress+0x19f9/0x2510 lib/lzo/lzo1x_compress.c:178
...
Uninit was stored to memory at:
ea_put fs/jfs/xattr.c:639 [inline]
...
Local variable ea_buf created at:
__jfs_setxattr+0x5d/0x1ae0 fs/jfs/xattr.c:662 __jfs_xattr_set+0xe6/0x1f0 fs/jfs/xattr.c:934
=====================================================
The reason is ea_buf->new_ea is not initialized properly.
Fix this by using memset to empty its content at the beginning in ea_get().
--- fs/jfs/xattr.c | 2 ++ 1 file changed, 2 insertions(+)
fs/jfs/xattr.c +2 -0
@@ -434,6 +434,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)int rc;int quota_allocation =0 ; +memset (&ea_buf->new_ea,0 ,sizeof (ea_buf->new_ea)); +/* When fsck.jfs clears a bad ea, it doesn't clear the size */ if (ji->ea.flag ==0 ) ea_size =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 458/691 drm/amdgpu: add raven1 gfxoff quirk
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Liu <[email protected]>
[ Upstream commit 0126c0ae11e8b52ecfde9d1b174ee2f32d6c3a5d ]
Fix screen corruption with openkylin.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -0
@@ -1274,6 +1274,8 @@ static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = { { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc6 },/* Apple MacBook Pro (15-inch, 2019) Radeon Pro Vega 20 4 GB */ { 0x1002, 0x69af, 0x106b, 0x019a, 0xc0 }, +/* https://bbs.openkylin.top/t/topic/171497 */ + { 0x1002, 0x15d8, 0x19e5, 0x3e14, 0xc2 }, { 0, 0, 0, 0, 0 }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 459/691 drm/amdgpu: enable gfxoff quirk on HP 705G4
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Liu <[email protected]>
[ Upstream commit 2c7795e245d993bcba2f716a8c93a5891ef910c9 ]
Enabling gfxoff quirk results in perfectly usable graphical user interface on HP 705G4 DM with R5 2400G.
Without the quirk, X server is completely unusable as every few seconds there is gpu reset due to ring gfx timeout.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -0
@@ -1276,6 +1276,8 @@ static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = { { 0x1002, 0x69af, 0x106b, 0x019a, 0xc0 },/* https://bbs.openkylin.top/t/topic/171497 */ { 0x1002, 0x15d8, 0x19e5, 0x3e14, 0xc2 }, +/* HP 705G4 DM with R5 2400G */ + { 0x1002, 0x15dd, 0x103c, 0x8464, 0xd6 }, { 0, 0, 0, 0, 0 }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 460/691 HID: multitouch: Add support for Thinkpad X12 Gen 2 Kbd Portfolio
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishnu Sankar <[email protected]>
[ Upstream commit 65b72ea91a257a5f0cb5a26b01194d3dd4b85298 ]
This applies similar quirks used by previous generation device, so that Trackpoint and buttons on the touchpad works. New USB KBD PID 0x61AE for Thinkpad X12 Tab is added.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 6 ++++++ 2 files changed, 7 insertions(+)
drivers/hid/hid-ids.h +1 -0
@@ -762,6 +762,7 @@#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5#define USB_DEVICE_ID_LENOVO_X12_TAB 0x60fe +#define USB_DEVICE_ID_LENOVO_X12_TAB2 0x61ae#define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
drivers/hid/hid-multitouch.c +6 -0
@@ -2114,6 +2114,12 @@ static const struct hid_device_id mt_devices[] = { USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X12_TAB) }, +/* Lenovo X12 TAB Gen 2 */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, +HID_DEVICE (BUS_USB ,HID_GROUP_MULTITOUCH_WIN_8 , +USB_VENDOR_ID_LENOVO , + USB_DEVICE_ID_LENOVO_X12_TAB2) }, + /* Logitech devices */ { .driver_data = MT_CLS_NSMU, HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 461/691 platform/x86: touchscreen_dmi: add nanote-next quirk
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ckath <[email protected]>
[ Upstream commit c11619af35bae5884029bd14170c3e4b55ddf6f3 ]
Add touschscreen info for the nanote next (UMPC-03-SR).
After checking with multiple owners the DMI info really is this generic.
--- drivers/platform/x86/touchscreen_dmi.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
drivers/platform/x86/touchscreen_dmi.c +26 -0
@@ -857,6 +857,21 @@ static const struct ts_dmi_data rwc_nanote_p8_data = { .properties = rwc_nanote_p8_props, }; +static const struct property_entry rwc_nanote_next_props[] = { +PROPERTY_ENTRY_U32 ("touchscreen-min-x" ,5 ), +PROPERTY_ENTRY_U32 ("touchscreen-min-y" ,5 ), +PROPERTY_ENTRY_U32 ("touchscreen-size-x" ,1785 ), +PROPERTY_ENTRY_U32 ("touchscreen-size-y" ,1145 ), +PROPERTY_ENTRY_BOOL ("touchscreen-inverted-y" ), +PROPERTY_ENTRY_STRING ("firmware-name" ,"gsl1680-rwc-nanote-next.fw" ), + { } +}; + +static const struct ts_dmi_data rwc_nanote_next_data = { + .acpi_name ="MSSL1680:00" , + .properties = rwc_nanote_next_props, +}; +static const struct property_entry schneider_sct101ctm_props[] = {PROPERTY_ENTRY_U32 ("touchscreen-size-x" ,1715 ),PROPERTY_ENTRY_U32 ("touchscreen-size-y" ,1140 ),
@@ -1588,6 +1603,17 @@ const struct dmi_system_id touchscreen_dmi_table[] = {DMI_MATCH (DMI_PRODUCT_SKU ,"0001" ) }, }, + { +/* RWC NANOTE NEXT */ + .driver_data = (void *)&rwc_nanote_next_data, + .matches = { +DMI_MATCH (DMI_PRODUCT_NAME ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_BOARD_NAME ,"To be filled by O.E.M." ), +DMI_MATCH (DMI_BOARD_VENDOR ,"To be filled by O.E.M." ), +/* Above matches are too generic, add bios-version match */ + DMI_MATCH(DMI_BIOS_VERSION, "S8A70R100-V005"), + }, + }, {/* Schneider SCT101CTM */ .driver_data = (void *)&schneider_sct101ctm_data,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 462/691 drm/amd/display: Check stream before comparing them
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 35ff747c86767937ee1e0ca987545b7eed7a0810 ]
[WHAT & HOW]amdgpu_dm can pass a null stream to dc_is_stream_unchanged. It is necessary to check for null before dereferencing them.
This fixes 1 FORWARD_NULL issue reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +2 -0
@@ -1623,6 +1623,8 @@ static bool are_stream_backends_same(bool dc_is_stream_unchanged (struct dc_stream_state *old_stream,struct dc_stream_state *stream) { +if (!old_stream || !stream) +return false;if (!are_stream_backends_same (old_stream, stream))return false;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 463/691 drm/amd/display: Fix index out of bounds in DCN30 degamma hardware format translation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit bc50b614d59990747dd5aeced9ec22f9258991ff ]
This commit addresses a potential index out of bounds issue in the cm3_helper_translate_curve_to_degamma_hw_format function in the DCN30 color management module. The issue could occur when the index 'i' exceeds the number of transfer function points (TRANSFER_FUNC_POINTS).
The fix adds a check to ensure 'i' is within bounds before accessing the transfer function points. If 'i' is out of bounds, the function returns false to indicate an error.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:338 cm3_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.red' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:339 cm3_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.green' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:340 cm3_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.blue' 1025 <= s32max
--- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +2 -0
@@ -355,6 +355,8 @@ bool cm3_helper_translate_curve_to_degamma_hw_format( i += increment) {if (j == hw_points -1 )break ; +if (i >=TRANSFER_FUNC_POINTS ) +return false; rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 464/691 drm/amd/display: Fix index out of bounds in degamma hardware format translation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit b7e99058eb2e86aabd7a10761e76cae33d22b49f ]
Fixes index out of bounds issue in cm_helper_translate_curve_to_degamma_hw_format function. The issue could occur when the index 'i' exceeds the number of transfer function points (TRANSFER_FUNC_POINTS).
The fix adds a check to ensure 'i' is within bounds before accessing the transfer function points. If 'i' is out of bounds the function returns false to indicate an error.
Reported by smatch:drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_cm_common.c:594 cm_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.red' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_cm_common.c:595 cm_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.green' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_cm_common.c:596 cm_helper_translate_curve_to_degamma_hw_format() error: buffer overflow 'output_tf->tf_pts.blue' 1025 <= s32max
--- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +2 -0
@@ -560,6 +560,8 @@ bool cm_helper_translate_curve_to_degamma_hw_format( i += increment) {if (j == hw_points -1 )break ; +if (i >=TRANSFER_FUNC_POINTS ) +return false; rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 465/691 drm/amd/display: Fix index out of bounds in DCN30 color transformation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit d81873f9e715b72d4f8d391c8eb243946f784dfc ]
This commit addresses a potential index out of bounds issue in the cm3_helper_translate_curve_to_hw_format function in the DCN30 color management module. The issue could occur when the index 'i' exceeds the number of transfer function points (TRANSFER_FUNC_POINTS).
The fix adds a check to ensure 'i' is within bounds before accessing the transfer function points. If 'i' is out of bounds, the function returns false to indicate an error.
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:180 cm3_helper_translate_curve_to_hw_format() error: buffer overflow 'output_tf->tf_pts.red' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:181 cm3_helper_translate_curve_to_hw_format() error: buffer overflow 'output_tf->tf_pts.green' 1025 <= s32max drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_cm_common.c:182 cm3_helper_translate_curve_to_hw_format() error: buffer overflow 'output_tf->tf_pts.blue' 1025 <= s32max
--- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c +2 -0
@@ -178,6 +178,8 @@ bool cm3_helper_translate_curve_to_hw_format( i += increment) {if (j == hw_points -1 )break ; +if (i >=TRANSFER_FUNC_POINTS ) +return false; rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 466/691 drm/amd/display: Initialize get_bytes_per_elements default to 1
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 4067f4fa0423a89fb19a30b57231b384d77d2610 ]
Variables, used as denominators and maybe not assigned to other values, should not be 0. bytes_per_element_y & bytes_per_element_c are initialized by get_bytes_per_element() which should never return 0.
This fixes 10 DIVIDE_BY_ZERO issues reported by Coverity.
--- .../gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 2 +- .../gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +1 -1
@@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,static unsigned int get_bytes_per_element (enum source_format_class source_format,bool is_chroma) { -unsigned int ret_val =0 ; +unsigned int ret_val =1 ;if (source_format == dm_444_16) {if (!is_chroma)
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +1 -1
@@ -53,7 +53,7 @@ static void calculate_ttu_cursor(static unsigned int get_bytes_per_element (enum source_format_class source_format,bool is_chroma) { -unsigned int ret_val =0 ; +unsigned int ret_val =1 ;if (source_format == dm_444_16) {if (!is_chroma)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 467/691 drm/printer: Allow NULL data in devcoredump printer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Brost <[email protected]>
[ Upstream commit 53369581dc0c68a5700ed51e1660f44c4b2bb524 ]
We want to determine the size of the devcoredump before writing it out. To that end, we will run the devcoredump printer with NULL data to get the size, alloc data based on the generated offset, then run the devcorecump again with a valid data pointer to print. This necessitates not writing data to the data pointer on the initial pass, when it is NULL.
v5:
- Better commit message (Jonathan)
- Add kerenl doc with examples (Jani)
--- drivers/gpu/drm/drm_print.c | 13 +++++---- include/drm/drm_print.h | 54 ++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 6 deletions(-)
drivers/gpu/drm/drm_print.c +8 -5
@@ -78,8 +78,9 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str) copy = iterator->remain;/* Copy out the bit of the string that we need */ -memcpy (iterator->data, - str + (iterator->start - iterator->offset), copy); +if (iterator->data) +memcpy (iterator->data, + str + (iterator->start - iterator->offset), copy); iterator->offset = iterator->start + copy; iterator->remain -= copy;
@@ -88,7 +89,8 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str) len =min_t (ssize_t,strlen (str), iterator->remain); -memcpy (iterator->data + pos, str, len); +if (iterator->data) +memcpy (iterator->data + pos, str, len); iterator->offset += len; iterator->remain -= len;
@@ -118,8 +120,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {ssize_t pos = iterator->offset - iterator->start; -snprintf (((char *) iterator->data) + pos, - iterator->remain,"%pV" , vaf); +if (iterator->data) +snprintf (((char *) iterator->data) + pos, + iterator->remain,"%pV" , vaf); iterator->offset += len; iterator->remain -= len;
include/drm/drm_print.h +53 -1
66 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 468/691 scsi: aacraid: Rearrange order of struct aac_srb_unit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit 6e5860b0ad4934baee8c7a202c02033b2631bb44 ]
struct aac_srb_unit contains struct aac_srb, which contains struct sgmap, which ends in a (currently) "fake" (1-element) flexible array. Converting this to a flexible array is needed so that runtime bounds checking won't think the array is fixed size (i.e. under CONFIG_FORTIFY_SOURCE=y and/or CONFIG_UBSAN_BOUNDS=y), as other parts of aacraid use struct sgmap as a flexible array.
It is not legal to have a flexible array in the middle of a structure, so it either needs to be split up or rearranged so that it is at the end of the structure. Luckily, struct aac_srb_unit, which is exclusively consumed/updated by aac_send_safw_bmic_cmd(), does not depend on member ordering.
The values set in the on-stack struct aac_srb_unit instance "srbu" by the only two callers, aac_issue_safw_bmic_identify() and aac_get_safw_ciss_luns(), do not contain anything in srbu.srb.sgmap.sg, and they both implicitly initialize srbu.srb.sgmap.count to 0 during memset(). For example:
memset(&srbu, 0, sizeof(struct aac_srb_unit));
srbcmd = &srbu.srb;
srbcmd->flags = cpu_to_le32(SRB_DataIn);
srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS;
srbcmd->cdb[1] = 2; /* extended reporting */
srbcmd->cdb[8] = (u8)(datasize >> 8);
srbcmd->cdb[9] = (u8)(datasize);
rcode = aac_send_safw_bmic_cmd(dev, &srbu, phys_luns, datasize);During aac_send_safw_bmic_cmd(), a separate srb is mapped into DMA, and has srbu.srb copied into it:
srb = fib_data(fibptr);
memcpy(srb, &srbu->srb, sizeof(struct aac_srb));Only then is srb.sgmap.count written and srb->sg populated:
srb->count = cpu_to_le32(xfer_len);
sg64 = (struct sgmap64 *)&srb->sg;
sg64->count = cpu_to_le32(1);
sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr));
sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr));
sg64->sg[0].count = cpu_to_le32(xfer_len);But this is happening in the DMA memory, not in srbu.srb. An attempt to copy the changes back to srbu does happen:
/*
* Copy the updated data for other dumping or other usage if
* needed
*/
memcpy(&srbu->srb, srb, sizeof(struct aac_srb));But this was never correct: the sg64 (3 u32s) overlap of srb.sg (2 u32s) always meant that srbu.srb would have held truncated information and any attempt to walk srbu.srb.sg.sg based on the value of srbu.srb.sg.count would result in attempting to parse past the end of srbu.srb.sg.sg[0] into srbu.srb_reply.
After getting a reply from hardware, the reply is copied into srbu.srb_reply:
srb_reply = (struct aac_srb_reply *)fib_data(fibptr);
memcpy(&srbu->srb_reply, srb_reply, sizeof(struct aac_srb_reply));This has always been fixed-size, so there's no issue here. It is worth noting that the two callers _never check_ srbu contents -- neither srbu.srb nor srbu.srb_reply is examined. (They depend on the mapped xfer_buf instead.)
Therefore, the ordering of members in struct aac_srb_unit does not matter, and the flexible array member can moved to the end.
(Additionally, the two memcpy()s that update srbu could be entirely removed as they are never consumed, but I left that as-is.)
--- drivers/scsi/aacraid/aacraid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/aacraid/aacraid.h +1 -1
@@ -2028,8 +2028,8 @@ struct aac_srb_reply };struct aac_srb_unit { -struct aac_srb srb;struct aac_srb_reply srb_reply; +struct aac_srb srb; };/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 469/691 drm/radeon/r100: Handle unknown family in r100_cp_init_microcode()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit c6dbab46324b1742b50dc2fb5c1fee2c28129439 ]
With -Werror:
In function ‘r100_cp_init_microcode’,
inlined from ‘r100_cp_init’ at drivers/gpu/drm/radeon/r100.c:1136:7:
include/linux/printk.h:465:44: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
465 | #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
| ^
include/linux/printk.h:437:17: note: in definition of macro ‘printk_index_wrap’
437 | _p_func(_fmt, ##__VA_ARGS__); \
| ^~~~~~~
include/linux/printk.h:508:9: note: in expansion of macro ‘printk’
508 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~
drivers/gpu/drm/radeon/r100.c:1062:17: note: in expansion of macro ‘pr_err’
1062 | pr_err("radeon_cp: Failed to load firmware \"%s\"\n", fw_name);
| ^~~~~~Fix this by converting the if/else if/... construct into a proper switch() statement with a default to handle the error case.
As a bonus, the generated code is ca. 100 bytes smaller (with gcc 11.4.0 targeting arm32).
--- drivers/gpu/drm/radeon/r100.c | 70 ++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 25 deletions(-)
drivers/gpu/drm/radeon/r100.c +45 -25
@@ -1014,45 +1014,65 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)DRM_DEBUG_KMS ("\n" ); -if ((rdev->family ==CHIP_R100 ) || (rdev->family ==CHIP_RV100 ) || - (rdev->family ==CHIP_RV200 ) || (rdev->family ==CHIP_RS100 ) || - (rdev->family ==CHIP_RS200 )) { +switch (rdev->family) { +case CHIP_R100 : +case CHIP_RV100 : +case CHIP_RV200 : +case CHIP_RS100 : +case CHIP_RS200 :DRM_INFO ("Loading R100 Microcode\n" ); fw_name =FIRMWARE_R100 ; - }else if ((rdev->family ==CHIP_R200 ) || - (rdev->family ==CHIP_RV250 ) || - (rdev->family ==CHIP_RV280 ) || - (rdev->family ==CHIP_RS300 )) { +break ; + +case CHIP_R200 : +case CHIP_RV250 : +case CHIP_RV280 : +case CHIP_RS300 :DRM_INFO ("Loading R200 Microcode\n" ); fw_name =FIRMWARE_R200 ; - }else if ((rdev->family ==CHIP_R300 ) || - (rdev->family ==CHIP_R350 ) || - (rdev->family ==CHIP_RV350 ) || - (rdev->family ==CHIP_RV380 ) || - (rdev->family ==CHIP_RS400 ) || - (rdev->family ==CHIP_RS480 )) { +break ; + +case CHIP_R300 : +case CHIP_R350 : +case CHIP_RV350 : +case CHIP_RV380 : +case CHIP_RS400 : +case CHIP_RS480 :DRM_INFO ("Loading R300 Microcode\n" ); fw_name =FIRMWARE_R300 ; - }else if ((rdev->family ==CHIP_R420 ) || - (rdev->family ==CHIP_R423 ) || - (rdev->family ==CHIP_RV410 )) { +break ; + +case CHIP_R420 : +case CHIP_R423 : +case CHIP_RV410 :DRM_INFO ("Loading R400 Microcode\n" ); fw_name =FIRMWARE_R420 ; - }else if ((rdev->family ==CHIP_RS690 ) || - (rdev->family ==CHIP_RS740 )) { +break ; + +case CHIP_RS690 : +case CHIP_RS740 :DRM_INFO ("Loading RS690/RS740 Microcode\n" ); fw_name =FIRMWARE_RS690 ; - }else if (rdev->family ==CHIP_RS600 ) { +break ; + +case CHIP_RS600 :DRM_INFO ("Loading RS600 Microcode\n" ); fw_name =FIRMWARE_RS600 ; - }else if ((rdev->family ==CHIP_RV515 ) || - (rdev->family ==CHIP_R520 ) || - (rdev->family ==CHIP_RV530 ) || - (rdev->family ==CHIP_R580 ) || - (rdev->family ==CHIP_RV560 ) || - (rdev->family ==CHIP_RV570 )) { +break ; + +case CHIP_RV515 : +case CHIP_R520 : +case CHIP_RV530 : +case CHIP_R580 : +case CHIP_RV560 : +case CHIP_RV570 :DRM_INFO ("Loading R500 Microcode\n" ); fw_name =FIRMWARE_R520 ; +break ; + +default : +DRM_ERROR ("Unsupported Radeon family %u\n" , rdev->family); +return -EINVAL ; } err =request_firmware (&rdev->me_fw, fw_name, rdev->dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 470/691 drm/amd/pm: ensure the fw_info is not null before using it
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 186fb12e7a7b038c2710ceb2fb74068f1b5d55a4 ]
This resolves the dereference null return value warning reported by Coverity.
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c +2 -0
@@ -1185,6 +1185,8 @@ static int init_overdrive_limits(struct pp_hwmgr *hwmgr, fw_info =smu_atom_get_data_table (hwmgr->adev,GetIndexIntoMasterTable (DATA , FirmwareInfo), &size, &frev, &crev); +PP_ASSERT_WITH_CODE (fw_info !=NULL , +"Missing firmware info!" , return -EINVAL );if ((fw_info->ucTableFormatRevision ==1 ) && (le16_to_cpu (fw_info->usStructureSize) >=sizeof (ATOM_FIRMWARE_INFO_V1_4 )))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 471/691 of/irq: Refer to actual buffer size in of_irq_parse_one()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit 39ab331ab5d377a18fbf5a0e0b228205edfcc7f4 ]
Replace two open-coded calculations of the buffer size by invocations of sizeof() on the buffer itself, to make sure the code will always use the actual buffer size.
--- drivers/of/irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/of/irq.c +2 -2
@@ -301,8 +301,8 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar addr =of_get_property (device,"reg" , &addr_len);/* Prevent out-of-bounds read in case of longer interrupt parent address size */ -if (addr_len > (3 *sizeof (__be32))) - addr_len =3 *sizeof (__be32); +if (addr_len >sizeof (addr_buf)) + addr_len =sizeof (addr_buf);if (addr)memcpy (addr_buf, addr, addr_len);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 472/691 ext4: ext4_search_dir should return a proper error
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo <[email protected]>
[ Upstream commit cd69f8f9de280e331c9e6ff689ced0a688a9ce8f ]
ext4_search_dir currently returns -1 in case of a failure, while it returns 0 when the name is not found. In such failure cases, it should return an error code instead.
This becomes even more important when ext4_find_inline_entry returns an error code as well in the next commit.
-EFSCORRUPTED seems appropriate as such error code as these failures would be caused by unexpected record lengths and is in line with other instances of ext4_check_dir_entry failures.
In the case of ext4_dx_find_entry, the current use of ERR_BAD_DX_DIR was left as is to reduce the risk of regressions.
--- fs/ext4/namei.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
fs/ext4/namei.c +7 -5
@@ -1526,7 +1526,7 @@ static bool ext4_match(struct inode *parent, }/* -* Returns 0 if not found, -1 on failure, and 1 on success +* Returns 0 if not found, -EFSCORRUPTED on failure, and 1 on success */ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size, struct inode *dir, struct ext4_filename *fname,
@@ -1547,7 +1547,7 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,* a full check */ if (ext4_check_dir_entry (dir,NULL , de, bh, search_buf, buf_size, offset)) -return -1 ; +return -EFSCORRUPTED ; *res_dir = de;return 1 ; }
@@ -1555,7 +1555,7 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size, de_len =ext4_rec_len_from_disk (de->rec_len, dir->i_sb->s_blocksize);if (de_len <=0 ) -return -1 ; +return -EFSCORRUPTED ; offset += de_len; de = (struct ext4_dir_entry_2 *) ((char *) de + de_len); }
@@ -1707,8 +1707,10 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir, goto cleanup_and_exit; }else {brelse (bh); -if (i <0 ) +if (i <0 ) { + ret =ERR_PTR (i); goto cleanup_and_exit; + } } next:if (++block >= nblocks)
@@ -1803,7 +1805,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir,if (retval ==1 ) goto success;brelse (bh); -if (retval ==-1 ) { +if (retval <0 ) { bh =ERR_PTR (ERR_BAD_DX_DIR ); goto errout; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 473/691 ext4: avoid use-after-free in ext4_ext_show_leaf()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
[ Upstream commit 4e2524ba2ca5f54bdbb9e5153bea00421ef653f5 ]
In ext4_find_extent(), path may be freed by error or be reallocated, so using a previously saved *ppath may have been freed and thus may trigger use-after-free, as follows:
ext4_split_extent
path = *ppath;
ext4_split_extent_at(ppath)
path = ext4_find_extent(ppath)
ext4_split_extent_at(ppath)
// ext4_find_extent fails to free path
// but zeroout succeeds ext4_ext_show_leaf(inode, path)
eh = path[depth].p_hdr
// path use-after-free !!!
Similar to ext4_split_extent_at(), we use *ppath directly as an input to ext4_ext_show_leaf(). Fix a spelling error by the way.
Same problem in ext4_ext_handle_unwritten_extents(). Since 'path' is only used in ext4_ext_show_leaf(), remove 'path' and use *ppath directly.
This issue is triggered only when EXT_DEBUG is defined and therefore does not affect functionality.
--- fs/ext4/extents.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
fs/ext4/extents.c +4 -5
@@ -3288,7 +3288,7 @@ static int ext4_split_extent_at(handle_t *handle, }/* -* ext4_split_extents() splits an extent and mark extent which is covered +* ext4_split_extent() splits an extent and mark extent which is covered * by @map as split_flags indicates * * It may result in splitting the extent into multiple extents (up to three)
@@ -3365,7 +3365,7 @@ static int ext4_split_extent(handle_t *handle, goto out; } -ext4_ext_show_leaf (inode, path); +ext4_ext_show_leaf (inode, *ppath); out:return err ? err : allocated; }
@@ -3831,14 +3831,13 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, int flags, unsigned int allocated, ext4_fsblk_t newblock) { - struct ext4_ext_path __maybe_unused *path = *ppath; int ret = 0;int err =0 ;ext_debug (inode,"logical block %llu, max_blocks %u, flags 0x%x, allocated %u\n" , (unsigned long long )map->m_lblk, map->m_len, flags, allocated); -ext4_ext_show_leaf (inode, path); +ext4_ext_show_leaf (inode, *ppath);/* * When writing into unwritten space, we should not fail to
@@ -3935,7 +3934,7 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,if (allocated > map->m_len) allocated = map->m_len; map->m_len = allocated; -ext4_ext_show_leaf (inode, path); +ext4_ext_show_leaf (inode, *ppath); out2:return err ? err : allocated; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 474/691 ext4: fix i_data_sem unlock order in ext4_ind_migrate()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Sadovnikov <[email protected]>
[ Upstream commit cc749e61c011c255d81b192a822db650c68b313f ]
Fuzzing reports a possible deadlock in jbd2_log_wait_commit.
This issue is triggered when an EXT4_IOC_MIGRATE ioctl is set to require synchronous updates because the file descriptor is opened with O_SYNC. This can lead to the jbd2_journal_stop() function calling jbd2_might_wait_for_commit(), potentially causing a deadlock if the EXT4_IOC_MIGRATE call races with a write(2) system call.
This problem only arises when CONFIG_PROVE_LOCKING is enabled. In this case, the jbd2_might_wait_for_commit macro locks jbd2_handle in the jbd2_journal_stop function while i_data_sem is locked. This triggers lockdep because the jbd2_journal_start function might also lock the same jbd2_handle simultaneously.
Found by Linux Verification Center (linuxtesting.org) with syzkaller.
Rule: add
--- fs/ext4/migrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/migrate.c +1 -1
@@ -663,8 +663,8 @@ int ext4_ind_migrate(struct inode *inode)if (unlikely (ret2 && !ret)) ret = ret2; errout: -ext4_journal_stop (handle);up_write (&EXT4_I (inode)->i_data_sem); +ext4_journal_stop (handle); out_unlock:percpu_up_write (&sbi->s_writepages_rwsem);return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 475/691 blk-integrity: use sysfs_emit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
Upstream commit 3315e169b446249c1b61ff988d157238f4b2c5a0.
The correct way to emit data into sysfs is via sysfs_emit(), use it.
Also perform some trivial syntactic cleanups.
--- block/blk-integrity.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
block/blk-integrity.c +9 -10
@@ -248,20 +248,19 @@ static ssize_t integrity_attr_store(struct kobject *kobj,static ssize_t integrity_format_show (struct blk_integrity *bi,char *page) {if (bi->profile && bi->profile->name) -return sprintf (page,"%s\n" , bi->profile->name); -else -return sprintf (page,"none\n" ); +return sysfs_emit (page,"%s\n" , bi->profile->name); +return sysfs_emit (page,"none\n" ); }static ssize_t integrity_tag_size_show (struct blk_integrity *bi,char *page) { -return sprintf (page,"%u\n" , bi->tag_size); +return sysfs_emit (page,"%u\n" , bi->tag_size); }static ssize_t integrity_interval_show (struct blk_integrity *bi,char *page) { -return sprintf (page,"%u\n" , - bi->interval_exp ?1 << bi->interval_exp :0 ); +return sysfs_emit (page,"%u\n" , + bi->interval_exp ?1 << bi->interval_exp :0 ); } static ssize_t integrity_verify_store(struct blk_integrity *bi,
@@ -280,7 +279,7 @@ static ssize_t integrity_verify_store(struct blk_integrity *bi,static ssize_t integrity_verify_show (struct blk_integrity *bi,char *page) { -return sprintf (page,"%d\n" , (bi->flags &BLK_INTEGRITY_VERIFY ) !=0 ); +return sysfs_emit (page,"%d\n" , !!(bi->flags &BLK_INTEGRITY_VERIFY )); } static ssize_t integrity_generate_store(struct blk_integrity *bi,
@@ -299,13 +298,13 @@ static ssize_t integrity_generate_store(struct blk_integrity *bi,static ssize_t integrity_generate_show (struct blk_integrity *bi,char *page) { -return sprintf (page,"%d\n" , (bi->flags &BLK_INTEGRITY_GENERATE ) !=0 ); +return sysfs_emit (page,"%d\n" , !!(bi->flags &BLK_INTEGRITY_GENERATE )); }static ssize_t integrity_device_show (struct blk_integrity *bi,char *page) { -return sprintf (page,"%u\n" , - (bi->flags &BLK_INTEGRITY_DEVICE_CAPABLE ) !=0 ); +return sysfs_emit (page,"%u\n" , + !!(bi->flags &BLK_INTEGRITY_DEVICE_CAPABLE )); }static struct integrity_sysfs_entry integrity_format_entry = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 476/691 blk-integrity: convert to struct device_attribute
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
Upstream commit 76b8c319f02715e14abdbbbdd6508e83a1059bcc.
An upcoming patch will register the integrity attributes directly with the struct device kobject.
For this the attributes have to be implemented in terms of struct device_attribute.
--- block/blk-integrity.c | 127 +++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 65 deletions(-)
block/blk-integrity.c +62 -65
@@ -212,21 +212,15 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,return true; } -struct integrity_sysfs_entry { -struct attribute attr; -ssize_t (*show)(struct blk_integrity *,char *); -ssize_t (*store)(struct blk_integrity *,const char *,size_t ); -}; -static ssize_t integrity_attr_show (struct kobject *kobj,struct attribute *attr,char *page) { struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj); -struct blk_integrity *bi = &disk->queue->integrity; -struct integrity_sysfs_entry *entry = - container_of(attr, struct integrity_sysfs_entry, attr); +struct device *dev =disk_to_dev (disk); +struct device_attribute *dev_attr = + container_of(attr, struct device_attribute, attr); -return entry->show (bi, page); +return dev_attr->show (dev, dev_attr, page); } static ssize_t integrity_attr_store(struct kobject *kobj,
@@ -234,38 +228,53 @@ static ssize_t integrity_attr_store(struct kobject *kobj, size_t count) { struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj); -struct blk_integrity *bi = &disk->queue->integrity; -struct integrity_sysfs_entry *entry = - container_of(attr, struct integrity_sysfs_entry, attr); -ssize_t ret =0 ; +struct device *dev =disk_to_dev (disk); +struct device_attribute *dev_attr = + container_of(attr, struct device_attribute, attr); -if (entry->store) - ret = entry->store (bi, page, count); +if (!dev_attr->store) +return 0 ; +return dev_attr->store (dev, dev_attr, page, count); +} -return ret; +static inline struct blk_integrity *dev_to_bi (struct device *dev) +{ +return &dev_to_disk (dev)->queue->integrity; } -static ssize_t integrity_format_show (struct blk_integrity *bi,char *page) +static ssize_t format_show (struct device *dev,struct device_attribute *attr, +char *page) { +struct blk_integrity *bi =dev_to_bi (dev); +if (bi->profile && bi->profile->name)return sysfs_emit (page,"%s\n" , bi->profile->name);return sysfs_emit (page,"none\n" ); } -static ssize_t integrity_tag_size_show (struct blk_integrity *bi,char *page) +static ssize_t tag_size_show (struct device *dev,struct device_attribute *attr, +char *page) { +struct blk_integrity *bi =dev_to_bi (dev); +return sysfs_emit (page,"%u\n" , bi->tag_size); } -static ssize_t integrity_interval_show (struct blk_integrity *bi,char *page) +static ssize_t protection_interval_bytes_show (struct device *dev, +struct device_attribute *attr, +char *page) { +struct blk_integrity *bi =dev_to_bi (dev); +return sysfs_emit (page,"%u\n" , bi->interval_exp ?1 << bi->interval_exp :0 ); } -static ssize_t integrity_verify_store (struct blk_integrity *bi, -const char *page,size_t count) +static ssize_t read_verify_store (struct device *dev, +struct device_attribute *attr, +const char *page,size_t count) { +struct blk_integrity *bi =dev_to_bi (dev);char *p = (char *) page;unsigned long val =simple_strtoul (p, &p,10 );
@@ -277,14 +286,20 @@ static ssize_t integrity_verify_store(struct blk_integrity *bi,return count; } -static ssize_t integrity_verify_show (struct blk_integrity *bi,char *page) +static ssize_t read_verify_show (struct device *dev, +struct device_attribute *attr,char *page) { +struct blk_integrity *bi =dev_to_bi (dev); +return sysfs_emit (page,"%d\n" , !!(bi->flags &BLK_INTEGRITY_VERIFY )); } -static ssize_t integrity_generate_store (struct blk_integrity *bi, -const char *page,size_t count) +static ssize_t write_generate_store (struct device *dev, +struct device_attribute *attr, +const char *page,size_t count) { +struct blk_integrity *bi =dev_to_bi (dev); +char *p = (char *) page;unsigned long val =simple_strtoul (p, &p,10 );
@@ -296,57 +311,39 @@ static ssize_t integrity_generate_store(struct blk_integrity *bi,return count; } -static ssize_t integrity_generate_show (struct blk_integrity *bi,char *page) +static ssize_t write_generate_show (struct device *dev, +struct device_attribute *attr,char *page) { +struct blk_integrity *bi =dev_to_bi (dev); +return sysfs_emit (page,"%d\n" , !!(bi->flags &BLK_INTEGRITY_GENERATE )); } -static ssize_t integrity_device_show (struct blk_integrity *bi,char *page) +static ssize_t device_is_integrity_capable_show (struct device *dev, +struct device_attribute *attr, +char *page) { +struct blk_integrity *bi =dev_to_bi (dev); +return sysfs_emit (page,"%u\n" , !!(bi->flags &BLK_INTEGRITY_DEVICE_CAPABLE )); } -static struct integrity_sysfs_entry integrity_format_entry = { - .attr = { .name ="format" , .mode =0444 }, - .show = integrity_format_show, -}; - -static struct integrity_sysfs_entry integrity_tag_size_entry = { - .attr = { .name ="tag_size" , .mode =0444 }, - .show = integrity_tag_size_show, -}; - -static struct integrity_sysfs_entry integrity_interval_entry = { - .attr = { .name ="protection_interval_bytes" , .mode =0444 }, - .show = integrity_interval_show, -}; - -static struct integrity_sysfs_entry integrity_verify_entry = { - .attr = { .name ="read_verify" , .mode =0644 }, - .show = integrity_verify_show, - .store = integrity_verify_store, -}; - -static struct integrity_sysfs_entry integrity_generate_entry = { - .attr = { .name ="write_generate" , .mode =0644 }, - .show = integrity_generate_show, - .store = integrity_generate_store, -}; - -static struct integrity_sysfs_entry integrity_device_entry = { - .attr = { .name ="device_is_integrity_capable" , .mode =0444 }, - .show = integrity_device_show, -}; +static DEVICE_ATTR_RO (format); +static DEVICE_ATTR_RO (tag_size); +static DEVICE_ATTR_RO (protection_interval_bytes); +static DEVICE_ATTR_RW (read_verify); +static DEVICE_ATTR_RW (write_generate); +static DEVICE_ATTR_RO (device_is_integrity_capable);static struct attribute *integrity_attrs[] = { - &integrity_format_entry.attr, - &integrity_tag_size_entry.attr, - &integrity_interval_entry.attr, - &integrity_verify_entry.attr, - &integrity_generate_entry.attr, - &integrity_device_entry.attr, -NULL , + &dev_attr_format.attr, + &dev_attr_tag_size.attr, + &dev_attr_protection_interval_bytes.attr, + &dev_attr_read_verify.attr, + &dev_attr_write_generate.attr, + &dev_attr_device_is_integrity_capable.attr, +NULL };ATTRIBUTE_GROUPS (integrity);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 477/691 blk-integrity: register sysfs attributes on struct device
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
Upstream commit ff53cd52d9bdbf4074d2bbe9b591729997780bd3.
The "integrity" kobject only acted as a holder for static sysfs entries. It also was embedded into struct gendisk without managing it, violating assumptions of the driver core.
Instead register the sysfs entries directly onto the struct device.
Also drop the now unused member integrity_kobj from struct gendisk.
--- block/blk-integrity.c | 55 +++---------------------------------------- block/blk.h | 10 +------- block/genhd.c | 12 ++++------ include/linux/genhd.h | 3 --- 4 files changed, 8 insertions(+), 72 deletions(-)
block/blk-integrity.c +3 -52
@@ -212,31 +212,6 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,return true; } -static ssize_t integrity_attr_show (struct kobject *kobj,struct attribute *attr, -char *page) -{ - struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj); -struct device *dev =disk_to_dev (disk); -struct device_attribute *dev_attr = - container_of(attr, struct device_attribute, attr); - -return dev_attr->show (dev, dev_attr, page); -} - -static ssize_t integrity_attr_store (struct kobject *kobj, -struct attribute *attr,const char *page, -size_t count) -{ - struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj); -struct device *dev =disk_to_dev (disk); -struct device_attribute *dev_attr = - container_of(attr, struct device_attribute, attr); - -if (!dev_attr->store) -return 0 ; -return dev_attr->store (dev, dev_attr, page, count); -} -static inline struct blk_integrity *dev_to_bi (struct device *dev) {return &dev_to_disk (dev)->queue->integrity;
@@ -345,16 +320,10 @@ static struct attribute *integrity_attrs[] = { &dev_attr_device_is_integrity_capable.attr, NULL }; -ATTRIBUTE_GROUPS (integrity); -static const struct sysfs_ops integrity_ops = { - .show = &integrity_attr_show, - .store = &integrity_attr_store, -}; - -static struct kobj_type integrity_ktype = { - .default_groups = integrity_groups, - .sysfs_ops = &integrity_ops, +const struct attribute_group blk_integrity_attr_group = { + .name ="integrity" , + .attrs = integrity_attrs, };static blk_status_t blk_integrity_nop_fn (struct blk_integrity_iter *iter)
@@ -431,21 +400,3 @@ void blk_integrity_unregister(struct gendisk *disk)memset (bi,0 ,sizeof (*bi)); }EXPORT_SYMBOL (blk_integrity_unregister); - -int blk_integrity_add (struct gendisk *disk) -{ -int ret; - - ret =kobject_init_and_add (&disk->integrity_kobj, &integrity_ktype, - &disk_to_dev (disk)->kobj,"%s" ,"integrity" ); -if (!ret) -kobject_uevent (&disk->integrity_kobj,KOBJ_ADD ); -return ret; -} - -void blk_integrity_del (struct gendisk *disk) -{ -kobject_uevent (&disk->integrity_kobj,KOBJ_REMOVE ); -kobject_del (&disk->integrity_kobj); -kobject_put (&disk->integrity_kobj); -}
block/blk.h +1 -9
@@ -130,8 +130,7 @@ static inline bool integrity_req_gap_front_merge(struct request *req, bip_next->bip_vec[0].bv_offset); } -int blk_integrity_add (struct gendisk *disk); -void blk_integrity_del (struct gendisk *); +extern const struct attribute_group blk_integrity_attr_group;#else /* CONFIG_BLK_DEV_INTEGRITY */ static inline bool blk_integrity_merge_rq (struct request_queue *rq,struct request *r1,struct request *r2)
@@ -164,13 +163,6 @@ static inline bool bio_integrity_endio(struct bio *bio)static inline void bio_integrity_free (struct bio *bio) { } -static inline int blk_integrity_add (struct gendisk *disk) -{ -return 0 ; -} -static inline void blk_integrity_del (struct gendisk *disk) -{ -}#endif /* CONFIG_BLK_DEV_INTEGRITY */ unsigned long blk_rq_timeout (unsigned long timeout);
block/genhd.c +4 -8
@@ -467,15 +467,11 @@ int device_add_disk(struct device *parent, struct gendisk *disk,*/ pm_runtime_set_memalloc_noio (ddev, true); - ret =blk_integrity_add (disk); -if (ret) - goto out_del_block_link; - disk->part0->bd_holder_dir =kobject_create_and_add ("holders" , &ddev->kobj);if (!disk->part0->bd_holder_dir) { ret = -ENOMEM ; - goto out_del_integrity; + goto out_del_block_link; } disk->slave_dir =kobject_create_and_add ("slaves" , &ddev->kobj);if (!disk->slave_dir) {
@@ -535,8 +531,6 @@ int device_add_disk(struct device *parent, struct gendisk *disk, disk->slave_dir =NULL ; out_put_holder_dir:kobject_put (disk->part0->bd_holder_dir); -out_del_integrity: -blk_integrity_del (disk); out_del_block_link:if (!sysfs_deprecated)sysfs_remove_link (block_depr,dev_name (ddev));
@@ -592,7 +586,6 @@ void del_gendisk(struct gendisk *disk)if (WARN_ON_ONCE (!disk_live (disk) && !(disk->flags &GENHD_FL_HIDDEN )))return ; -blk_integrity_del (disk);disk_del_events (disk);mutex_lock (&disk->open_mutex);
@@ -1084,6 +1077,9 @@ static struct attribute_group disk_attr_group = {static const struct attribute_group *disk_attr_groups[] = { &disk_attr_group, +#ifdef CONFIG_BLK_DEV_INTEGRITY + &blk_integrity_attr_group, +#endifNULL };
include/linux/genhd.h +0 -3
@@ -144,9 +144,6 @@ struct gendisk {struct timer_rand_state *random;atomic_t sync_io;/* RAID */ struct disk_events *ev; -#ifdef CONFIG_BLK_DEV_INTEGRITY -struct kobject integrity_kobj; -#endif /* CONFIG_BLK_DEV_INTEGRITY */ #if IS_ENABLED (CONFIG_CDROM )struct cdrom_device_info *cdi;#endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 478/691 usb: typec: tcpm: Check for port partner validity before consuming it
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Badhri Jagan Sridharan <[email protected]>
commit ae11f04b452b5205536e1c02d31f8045eba249dd upstream.
typec_register_partner() does not guarantee partner registration to always succeed. In the event of failure, port->partner is set to the error value or NULL. Given that port->partner validity is not checked, this results in the following crash:
Unable to handle kernel NULL pointer dereference at virtual address xx pc : run_state_machine+0x1bc8/0x1c08 lr : run_state_machine+0x1b90/0x1c08 .. Call trace: run_state_machine+0x1bc8/0x1c08 tcpm_state_machine_work+0x94/0xe4 kthread_worker_fn+0x118/0x328 kthread+0x1d0/0x23c ret_from_fork+0x10/0x20
To prevent the crash, check for port->partner validity before derefencing it in all the call sites.
[Sherry: bp to 5.15.y, minor conflicts due to missing commit:
8203d26905ee ("usb: typec: tcpm: Register USB Power Delivery
Capabilities"). Ignore the the part typec_partner_set_usb_power_delivery() which is not in 5.15.y.]
--- drivers/usb/typec/tcpm/tcpm.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
drivers/usb/typec/tcpm/tcpm.c +22 -6
@@ -1471,7 +1471,8 @@ static void svdm_consume_identity(struct tcpm_port *port, const u32 *p, int cnt) port->partner_ident.cert_stat = p[VDO_INDEX_CSTAT ]; port->partner_ident.product = product; -typec_partner_set_identity (port->partner); +if (port->partner) +typec_partner_set_identity (port->partner); tcpm_log(port, "Identity: %04x:%04x.%04x", PD_IDH_VID(vdo),
@@ -1559,6 +1560,9 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port)struct typec_altmode *altmode;int i; +if (!port->partner) +return ; +for (i =0 ; i < modep->altmodes; i++) { altmode =typec_partner_register_altmode (port->partner, &modep->altmode_desc[i]);
@@ -3577,7 +3581,10 @@ static int tcpm_init_vconn(struct tcpm_port *port)static void tcpm_typec_connect (struct tcpm_port *port) { +struct typec_partner *partner; +if (!port->connected) { + port->connected = true;/* Make sure we don't report stale identity information */ memset (&port->partner_ident,0 ,sizeof (port->partner_ident)); port->partner_desc.usb_pd = port->pd_capable;
@@ -3587,9 +3594,13 @@ static void tcpm_typec_connect(struct tcpm_port *port) port->partner_desc.accessory =TYPEC_ACCESSORY_AUDIO ; else port->partner_desc.accessory = TYPEC_ACCESSORY_NONE; - port->partner =typec_register_partner (port->typec_port, - &port->partner_desc); - port->connected = true; + partner =typec_register_partner (port->typec_port, &port->partner_desc); +if (IS_ERR (partner)) { +dev_err (port->dev,"Failed to register partner (%ld)\n" ,PTR_ERR (partner)); +return ; + } + + port->partner = partner; } }
@@ -3658,8 +3669,10 @@ static int tcpm_src_attach(struct tcpm_port *port)static void tcpm_typec_disconnect (struct tcpm_port *port) {if (port->connected) { -typec_unregister_partner (port->partner); - port->partner =NULL ; +if (port->partner) { +typec_unregister_partner (port->partner); + port->partner =NULL ; + } port->connected = false; } }
@@ -3868,6 +3881,9 @@ static enum typec_cc_status tcpm_pwr_opmode_to_rp(enum typec_pwr_opmode opmode)static void tcpm_set_initial_svdm_version (struct tcpm_port *port) { +if (!port->partner) +return ; +switch (port->negotiated_rev) {case PD_REV30 :break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 479/691 spi: spi-imx: Fix pm_runtime_set_suspended() with runtime pm enabled
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit b6e05ba0844139dde138625906015c974c86aa93 ]
It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it.
--- drivers/spi/spi-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-imx.c +1 -1
@@ -1761,8 +1761,8 @@ static int spi_imx_probe(struct platform_device *pdev)spi_imx_sdma_exit (spi_imx); out_runtime_pm_put:pm_runtime_dont_use_autosuspend (spi_imx->dev); -pm_runtime_set_suspended (&pdev->dev);pm_runtime_disable (spi_imx->dev); +pm_runtime_set_suspended (&pdev->dev);clk_disable_unprepare (spi_imx->clk_ipg); out_put_per:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 480/691 spi: s3c64xx: fix timeout counters in flush_fifo
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks <[email protected]>
[ Upstream commit 68a16708d2503b6303d67abd43801e2ca40c208d ]
In the s3c64xx_flush_fifo() code, the loops counter is post-decremented in the do { } while(test && loops--) condition. This means the loops is left at the unsigned equivalent of -1 if the loop times out. The test after will never pass as if tests for loops == 0.
--- drivers/spi/spi-s3c64xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi-s3c64xx.c +2 -2
@@ -216,7 +216,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) loops =msecs_to_loops (1 );do { val =readl (regs +S3C64XX_SPI_STATUS ); - }while (TX_FIFO_LVL (val, sdd) && loops--); + }while (TX_FIFO_LVL (val, sdd) && --loops);if (loops ==0 )dev_warn (&sdd->pdev->dev,"Timed out flushing TX FIFO\n" );
@@ -229,7 +229,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd)readl (regs +S3C64XX_SPI_RX_DATA ); else break; - }while (loops--); + }while (--loops);if (loops ==0 )dev_warn (&sdd->pdev->dev,"Timed out flushing RX FIFO\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 481/691 selftests: breakpoints: use remaining time to check if suspend succeed
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifei Liu <[email protected]>
[ Upstream commit c66be905cda24fb782b91053b196bd2e966f95b7 ]
step_after_suspend_test fails with device busy error while writing to /sys/power/state to start suspend. The test believes it failed to enter suspend state with
$ sudo ./step_after_suspend_test TAP version 13 Bail out! Failed to enter Suspend state
However, in the kernel message, I indeed see the system get suspended and then wake up later.
[611172.033108] PM: suspend entry (s2idle) [611172.044940] Filesystems sync: 0.006 seconds [611172.052254] Freezing user space processes [611172.059319] Freezing user space processes completed (elapsed 0.001 seconds) [611172.067920] OOM killer disabled. [611172.072465] Freezing remaining freezable tasks [611172.080332] Freezing remaining freezable tasks completed (elapsed 0.001 seconds) [611172.089724] printk: Suspending console(s) (use no_console_suspend to debug) [611172.117126] serial 00:03: disabled some other hardware get reconnected [611203.136277] OOM killer enabled. [611203.140637] Restarting tasks ... [611203.141135] usb 1-8.1: USB disconnect, device number 7 [611203.141755] done. [611203.155268] random: crng reseeded on system resumption [611203.162059] PM: suspend exit
After investigation, I noticed that for the code block if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem"))
ksft_exit_fail_msg("Failed to enter Suspend state\n");The write will return -1 and errno is set to 16 (device busy). It should be caused by the write function is not successfully returned before the system suspend and the return value get messed when waking up. As a result, It may be better to check the time passed of those few instructions to determine whether the suspend is executed correctly for it is pretty hard to execute those few lines for 5 seconds.
The timer to wake up the system is set to expire after 5 seconds and no re-arm. If the timer remaining time is 0 second and 0 nano secomd, it means the timer expired and wake the system up. Otherwise, the system could be considered to enter the suspend state failed if there is any remaining time.
After appling this patch, the test would not fail for it believes the system does not go to suspend by mistake. It now could continue to the rest part of the test after suspend.
--- .../testing/selftests/breakpoints/step_after_suspend_test.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/testing/selftests/breakpoints/step_after_suspend_test.c +4 -1
@@ -153,7 +153,10 @@ void suspend(void)if (err <0 )ksft_exit_fail_msg ("timerfd_settime() failed\n" ); -if (write (power_state_fd,"mem" ,strlen ("mem" )) !=strlen ("mem" )) +system ("(echo mem > /sys/power/state) 2> /dev/null" ); + +timerfd_gettime (timerfd, &spec); +if (spec.it_value.tv_sec !=0 || spec.it_value.tv_nsec !=0 )ksft_exit_fail_msg ("Failed to enter Suspend state\n" );close (timerfd);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 482/691 selftests: vDSO: fix vDSO name for powerpc
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit 59eb856c3ed9b3552befd240c0c339f22eed3fa1 ]
Following error occurs when running vdso_test_correctness on powerpc:
~ # ./vdso_test_correctness
[WARN] failed to find vDSO
[SKIP] No vDSO, so skipping clock_gettime() tests
[SKIP] No vDSO, so skipping clock_gettime64() tests
[RUN] Testing getcpu...
[OK] CPU 0: syscall: cpu 0, node 0
On powerpc, vDSO is neither called linux-vdso.so.1 nor linux-gate.so.1 but linux-vdso32.so.1 or linux-vdso64.so.1.
Also search those two names before giving up.
--- tools/testing/selftests/vDSO/vdso_test_correctness.c | 6 ++++++ 1 file changed, 6 insertions(+)
tools/testing/selftests/vDSO/vdso_test_correctness.c +6 -0
@@ -113,6 +113,12 @@ static void fill_function_pointers()if (!vdso) vdso =dlopen ("linux-gate.so.1" ,RTLD_LAZY |RTLD_LOCAL |RTLD_NOLOAD ); +if (!vdso) + vdso =dlopen ("linux-vdso32.so.1" , +RTLD_LAZY |RTLD_LOCAL |RTLD_NOLOAD ); +if (!vdso) + vdso =dlopen ("linux-vdso64.so.1" , +RTLD_LAZY |RTLD_LOCAL |RTLD_NOLOAD );if (!vdso) {printf ("[WARN]\tfailed to find vDSO\n" );return ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 483/691 selftests: vDSO: fix vdso_config for powerpc
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit 7d297c419b08eafa69ce27243ee9bbecab4fcaa4 ]
Running vdso_test_correctness on powerpc64 gives the following warning:
~ # ./vdso_test_correctness
Warning: failed to find clock_gettime64 in vDSO
This is because vdso_test_correctness was built with VDSO_32BIT defined.
__powerpc__ macro is defined on both powerpc32 and powerpc64 so __powerpc64__ needs to be checked first in vdso_config.h
--- tools/testing/selftests/vDSO/vdso_config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/vDSO/vdso_config.h +3 -3
@@ -18,13 +18,13 @@#elif defined(__aarch64__)#define VDSO_VERSION 3#define VDSO_NAMES 0 -#elif defined(__powerpc__) +#elif defined(__powerpc64__)#define VDSO_VERSION 1#define VDSO_NAMES 0 -#define VDSO_32BIT 1 -#elif defined(__powerpc64__) +#elif defined(__powerpc__)#define VDSO_VERSION 1#define VDSO_NAMES 0 +#define VDSO_32BIT 1#elif defined (__s390__)#define VDSO_VERSION 2#define VDSO_NAMES 0
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 484/691 selftests: vDSO: fix vDSO symbols lookup for powerpc64
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit ba83b3239e657469709d15dcea5f9b65bf9dbf34 ]
On powerpc64, following tests fail locating vDSO functions:
~ # ./vdso_test_abi
TAP version 13
1..16
# [vDSO kselftest] VDSO_VERSION: LINUX_2.6.15 # Couldn't find __kernel_gettimeofday
ok 1 # SKIP __kernel_gettimeofday
# clock_id: CLOCK_REALTIME
# Couldn't find __kernel_clock_gettime
ok 2 # SKIP __kernel_clock_gettime CLOCK_REALTIME # Couldn't find __kernel_clock_getres
ok 3 # SKIP __kernel_clock_getres CLOCK_REALTIME
...
# Couldn't find __kernel_time
ok 16 # SKIP __kernel_time
# Totals: pass:0 fail:0 xfail:0 xpass:0 skip:16 error:0
~ # ./vdso_test_getrandom
__kernel_getrandom is missing!
~ # ./vdso_test_gettimeofday
Could not find __kernel_gettimeofday
~ # ./vdso_test_getcpu
Could not find __kernel_getcpu
On powerpc64, as shown below by readelf, vDSO functions symbols have type NOTYPE, so also accept that type when looking for symbols.
$ powerpc64-linux-gnu-readelf -a arch/powerpc/kernel/vdso/vdso64.so.dbg ELF Header: Magic: 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, big endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: PowerPC64 Version: 0x1 ...
Symbol table '.dynsym' contains 12 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000524 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
2: 00000000000005f0 36 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
3: 0000000000000578 68 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
4: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6.15
5: 00000000000006c0 48 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
6: 0000000000000614 172 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
7: 00000000000006f0 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
8: 000000000000047c 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
9: 0000000000000454 12 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
10: 00000000000004d0 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
11: 00000000000005bc 52 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15Symbol table '.symtab' contains 56 entries:
Num: Value Size Type Bind Vis Ndx Name
...
45: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6.15
46: 00000000000006c0 48 NOTYPE GLOBAL DEFAULT 8 __kernel_getcpu
47: 0000000000000524 84 NOTYPE GLOBAL DEFAULT 8 __kernel_clock_getres
48: 00000000000005f0 36 NOTYPE GLOBAL DEFAULT 8 __kernel_get_tbfreq
49: 000000000000047c 84 NOTYPE GLOBAL DEFAULT 8 __kernel_gettimeofday
50: 0000000000000614 172 NOTYPE GLOBAL DEFAULT 8 __kernel_sync_dicache
51: 00000000000006f0 84 NOTYPE GLOBAL DEFAULT 8 __kernel_getrandom
52: 0000000000000454 12 NOTYPE GLOBAL DEFAULT 8 __kernel_sigtram[...]
53: 0000000000000578 68 NOTYPE GLOBAL DEFAULT 8 __kernel_time
54: 00000000000004d0 84 NOTYPE GLOBAL DEFAULT 8 __kernel_clock_g[...]
55: 00000000000005bc 52 NOTYPE GLOBAL DEFAULT 8 __kernel_get_sys[...]--- tools/testing/selftests/vDSO/parse_vdso.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/vDSO/parse_vdso.c +2 -1
@@ -216,7 +216,8 @@ void *vdso_sym(const char *version, const char *name)ELF (Sym) *sym = &vdso_info.symtab[chain];/* Check for a defined global or weak function w/ right name. */ -if (ELF64_ST_TYPE (sym->st_info) !=STT_FUNC ) +if (ELF64_ST_TYPE (sym->st_info) !=STT_FUNC && +ELF64_ST_TYPE (sym->st_info) !=STT_NOTYPE )continue ;if (ELF64_ST_BIND (sym->st_info) !=STB_GLOBAL &&ELF64_ST_BIND (sym->st_info) !=STB_WEAK )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 485/691 selftests/mm: fix charge_reserved_hugetlb.sh test
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit c41a701d18efe6b8aa402efab16edbaba50c9548 ]
Currently, running the charge_reserved_hugetlb.sh selftest we can sometimes observe something like:
$ ./charge_reserved_hugetlb.sh -cgroup-v2 ... write_result is 0 After write: hugetlb_usage=0 reserved_usage=10485760 killing write_to_hugetlbfs Received 2. Deleting the memory Detach failure: Invalid argument umount: /mnt/huge: target is busy.
Both cases are issues in the test.
While the unmount error seems to be racy, it will make the test fail:
$ ./run_vmtests.sh -t hugetlb ... # [FAIL] not ok 10 charge_reserved_hugetlb.sh -cgroup-v2 # exit=32
The issue is that we are not waiting for the write_to_hugetlbfs process to quit. So it might still have a hugetlbfs file open, about which umount is not happy. Fix that by making "killall" wait for the process to quit.
The other error ("Detach failure: Invalid argument") does not seem to result in a test error, but is misleading. Turns out write_to_hugetlbfs.c unconditionally tries to cleanup using shmdt(), even when we only mmap()'ed a hugetlb file. Even worse, shmaddr is never even set for the SHM case. Fix that as well.
With this change it seems to work as expected.
--- .../selftests/vm/charge_reserved_hugetlb.sh | 2 +- .../testing/selftests/vm/write_to_hugetlbfs.c | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-)
tools/testing/selftests/vm/charge_reserved_hugetlb.sh +1 -1
@@ -252,7 +252,7 @@ function cleanup_hugetlb_memory() { local cgroup="$1" if [[ "$(pgrep -f write_to_hugetlbfs)" != "" ]]; then echo killing write_to_hugetlbfs - killall -2 write_to_hugetlbfs + killall -2 --wait write_to_hugetlbfs wait_for_hugetlb_memory_to_get_depleted $cgroup fi set -e
tools/testing/selftests/vm/write_to_hugetlbfs.c +12 -9
@@ -28,7 +28,7 @@ enum method {/* Global variables. */ static const char *self; -static char *shmaddr; +static int *shmaddr;static int shmid;/*
@@ -47,15 +47,17 @@ void sig_handler(int signo) {printf ("Received %d.\n" , signo);if (signo ==SIGINT ) { -printf ("Deleting the memory\n" ); -if (shmdt ((const void *)shmaddr) !=0 ) { -perror ("Detach failure" ); +if (shmaddr) { +printf ("Deleting the memory\n" ); +if (shmdt ((const void *)shmaddr) !=0 ) { +perror ("Detach failure" ); +shmctl (shmid,IPC_RMID ,NULL ); +exit (4 ); + } +shmctl (shmid,IPC_RMID ,NULL ); -exit (4 ); +printf ("Done deleting the memory\n" ); } - -shmctl (shmid,IPC_RMID ,NULL ); -printf ("Done deleting the memory\n" ); }exit (2 ); }
@@ -211,7 +213,8 @@ int main(int argc, char **argv)shmctl (shmid,IPC_RMID ,NULL );exit (2 ); } -printf ("shmaddr: %p\n" , ptr); + shmaddr = ptr; +printf ("shmaddr: %p\n" , shmaddr);break ;default :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 486/691 selftests: vDSO: fix ELF hash table entry size for s390x
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Remus <[email protected]>
[ Upstream commit 14be4e6f35221c4731b004553ecf7cbc6dc1d2d8 ]
The vDSO self tests fail on s390x for a vDSO linked with the GNU linker ld as follows:
# ./vdso_test_gettimeofday Floating point exception (core dumped)
On s390x the ELF hash table entries are 64 bits instead of 32 bits in size (see Glibc sysdeps/unix/sysv/linux/s390/bits/elfclass.h).
--- tools/testing/selftests/vDSO/parse_vdso.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
tools/testing/selftests/vDSO/parse_vdso.c +10 -4
@@ -36,6 +36,12 @@#define ELF_BITS_XFORM (bits, x) ELF_BITS_XFORM2(bits, x)#define ELF (x) ELF_BITS_XFORM(ELF_BITS, x) +#ifdef __s390x__ +#define ELF_HASH_ENTRY ELF(Xword) +#else +#define ELF_HASH_ENTRY ELF(Word) +#endif + static struct vdso_info { bool valid;
@@ -47,8 +53,8 @@ static struct vdso_info/* Symbol table */ ELF (Sym) *symtab;const char *symstrings; -ELF (Word) *bucket, *chain; -ELF (Word) nbucket, nchain; +ELF_HASH_ENTRY *bucket, *chain; +ELF_HASH_ENTRY nbucket, nchain;/* Version table */ ELF (Versym) *versym;
@@ -115,7 +121,7 @@ void vdso_init_from_sysinfo_ehdr(uintptr_t base)/* * Fish out the useful bits of the dynamic table. */ -ELF (Word) *hash =0 ; +ELF_HASH_ENTRY *hash =0 ; vdso_info.symstrings =0 ; vdso_info.symtab =0 ; vdso_info.versym =0 ;
@@ -133,7 +139,7 @@ void vdso_init_from_sysinfo_ehdr(uintptr_t base) + vdso_info.load_offset);break ;case DT_HASH : - hash = (ELF (Word) *) + hash = (ELF_HASH_ENTRY *) ((uintptr_t )dyn[i].d_un.d_ptr + vdso_info.load_offset);break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 487/691 selftests: vDSO: fix vdso_config for s390
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
[ Upstream commit a6e23fb8d3c0e3904da70beaf5d7e840a983c97f ]
Running vdso_test_correctness on s390x (aka s390 64 bit) emits a warning:
Warning: failed to find clock_gettime64 in vDSO
This is caused by the "#elif defined (__s390__)" check in vdso_config.h which the defines VDSO_32BIT.
If __s390x__ is defined also __s390__ is defined. Therefore the correct check must make sure that only __s390__ is defined.
Therefore add the missing !defined(__s390x__). Also use common __s390x__ define instead of __s390X__.
--- tools/testing/selftests/vDSO/vdso_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/vDSO/vdso_config.h +2 -2
@@ -25,11 +25,11 @@#define VDSO_VERSION 1#define VDSO_NAMES 0#define VDSO_32BIT 1 -#elif defined (__s390__) +#elif defined (__s390__) && !defined(__s390x__)#define VDSO_VERSION 2#define VDSO_NAMES 0#define VDSO_32BIT 1 -#elif defined (__s390X__) +#elif defined (__s390x__)#define VDSO_VERSION 2#define VDSO_NAMES 0#elif defined(__mips__)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 488/691 platform/x86: ISST: Fix the KASAN report slab-out-of-bounds bug
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zach Wade <[email protected]>
commit 7d59ac07ccb58f8f604f8057db63b8efcebeb3de upstream.
Attaching SST PCI device to VM causes "BUG: KASAN: slab-out-of-bounds". kasan report:
[ 19.411889] ================================================================== [ 19.413702] BUG: KASAN: slab-out-of-bounds in _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.415634] Read of size 8 at addr ffff888829e65200 by task cpuhp/16/113 [ 19.417368] [ 19.418627] CPU: 16 PID: 113 Comm: cpuhp/16 Tainted: G E 6.9.0 #10 [ 19.420435] Hardware name: VMware, Inc. VMware20,1/440BX Desktop Reference Platform, BIOS VMW201.00V.20192059.B64.2207280713 07/28/2022 [ 19.422687] Call Trace: [ 19.424091] <TASK> [ 19.425448] dump_stack_lvl+0x5d/0x80 [ 19.426963] ? _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.428694] print_report+0x19d/0x52e [ 19.430206] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 19.431837] ? _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.433539] kasan_report+0xf0/0x170 [ 19.435019] ? _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.436709] _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.438379] ? __pfx_sched_clock_cpu+0x10/0x10 [ 19.439910] isst_if_cpu_online+0x406/0x58f [isst_if_common] [ 19.441573] ? __pfx_isst_if_cpu_online+0x10/0x10 [isst_if_common] [ 19.443263] ? ttwu_queue_wakelist+0x2c1/0x360 [ 19.444797] cpuhp_invoke_callback+0x221/0xec0 [ 19.446337] cpuhp_thread_fun+0x21b/0x610 [ 19.447814] ? __pfx_cpuhp_thread_fun+0x10/0x10 [ 19.449354] smpboot_thread_fn+0x2e7/0x6e0 [ 19.450859] ? __pfx_smpboot_thread_fn+0x10/0x10 [ 19.452405] kthread+0x29c/0x350 [ 19.453817] ? __pfx_kthread+0x10/0x10 [ 19.455253] ret_from_fork+0x31/0x70 [ 19.456685] ? __pfx_kthread+0x10/0x10 [ 19.458114] ret_from_fork_asm+0x1a/0x30 [ 19.459573] </TASK> [ 19.460853] [ 19.462055] Allocated by task 1198: [ 19.463410] kasan_save_stack+0x30/0x50 [ 19.464788] kasan_save_track+0x14/0x30 [ 19.466139] __kasan_kmalloc+0xaa/0xb0 [ 19.467465] __kmalloc+0x1cd/0x470 [ 19.468748] isst_if_cdev_register+0x1da/0x350 [isst_if_common] [ 19.470233] isst_if_mbox_init+0x108/0xff0 [isst_if_mbox_msr] [ 19.471670] do_one_initcall+0xa4/0x380 [ 19.472903] do_init_module+0x238/0x760 [ 19.474105] load_module+0x5239/0x6f00 [ 19.475285] init_module_from_file+0xd1/0x130 [ 19.476506] idempotent_init_module+0x23b/0x650 [ 19.477725] __x64_sys_finit_module+0xbe/0x130 [ 19.476506] idempotent_init_module+0x23b/0x650 [ 19.477725] __x64_sys_finit_module+0xbe/0x130 [ 19.478920] do_syscall_64+0x82/0x160 [ 19.480036] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 19.481292] [ 19.482205] The buggy address belongs to the object at ffff888829e65000 which belongs to the cache kmalloc-512 of size 512 [ 19.484818] The buggy address is located 0 bytes to the right of allocated 512-byte region [ffff888829e65000, ffff888829e65200) [ 19.487447] [ 19.488328] The buggy address belongs to the physical page: [ 19.489569] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff888829e60c00 pfn:0x829e60 [ 19.491140] head: order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 19.492466] anon flags: 0x57ffffc0000840(slab|head|node=1|zone=2|lastcpupid=0x1fffff) [ 19.493914] page_type: 0xffffffff() [ 19.494988] raw: 0057ffffc0000840 ffff88810004cc80 0000000000000000 0000000000000001 [ 19.496451] raw: ffff888829e60c00 0000000080200018 00000001ffffffff 0000000000000000 [ 19.497906] head: 0057ffffc0000840 ffff88810004cc80 0000000000000000 0000000000000001 [ 19.499379] head: ffff888829e60c00 0000000080200018 00000001ffffffff 0000000000000000 [ 19.500844] head: 0057ffffc0000003 ffffea0020a79801 ffffea0020a79848 00000000ffffffff [ 19.502316] head: 0000000800000000 0000000000000000 00000000ffffffff 0000000000000000 [ 19.503784] page dumped because: kasan: bad access detected [ 19.505058] [ 19.505970] Memory state around the buggy address: [ 19.507172] ffff888829e65100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 19.508599] ffff888829e65180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 19.510013] >ffff888829e65200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 19.510014] ^ [ 19.510016] ffff888829e65280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 19.510018] ffff888829e65300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 19.515367] ==================================================================
The reason for this error is physical_package_ids assigned by VMware VMM are not continuous and have gaps. This will cause value returned by topology_physical_package_id() to be more than topology_max_packages().
Here the allocation uses topology_max_packages(). The call to topology_max_packages() returns maximum logical package ID not physical ID. Hence use topology_logical_package_id() instead of topology_physical_package_id().
--- drivers/platform/x86/intel/speed_select_if/isst_if_common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/platform/x86/intel/speed_select_if/isst_if_common.c +3 -1
@@ -306,7 +306,9 @@ static struct pci_dev *_isst_if_get_pci_ cpu >= nr_cpu_ids || cpu >= num_possible_cpus())return NULL ; - pkg_id =topology_physical_package_id (cpu); + pkg_id =topology_logical_package_id (cpu); +if (pkg_id >=topology_max_packages ()) +return NULL ; bus_number = isst_cpu_info[cpu].bus_info[bus_no];if (bus_number <0 )
Greg Kroah-Hartman
maintainerPATCH 489/691 i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
commit 048bbbdbf85e5e00258dfb12f5e368f908801d7b upstream.
In case there is any sort of clock controller attached to this I2C bus controller, for example Versaclock or even an AIC32x4 I2C codec, then an I2C transfer triggered from the clock controller clk_ops .prepare callback may trigger a deadlock on drivers/clk/clk.c prepare_lock mutex.
This is because the clock controller first grabs the prepare_lock mutex and then performs the prepare operation, including its I2C access. The I2C access resumes this I2C bus controller via .runtime_resume callback, which calls clk_prepare_enable(), which attempts to grab the prepare_lock mutex again and deadlocks.
Since the clock are already prepared since probe() and unprepared in remove(), use simple clk_enable()/clk_disable() calls to enable and disable the clock on runtime suspend and resume, to avoid hitting the prepare_lock mutex.
--- drivers/i2c/busses/i2c-stm32f7.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/i2c/busses/i2c-stm32f7.c +3 -3
@@ -2351,7 +2351,7 @@ static int __maybe_unused stm32f7_i2c_rustruct stm32f7_i2c_dev *i2c_dev =dev_get_drvdata (dev);if (!stm32f7_i2c_is_slave_registered (i2c_dev)) -clk_disable_unprepare (i2c_dev->clk); +clk_disable (i2c_dev->clk);return 0 ; }
@@ -2362,9 +2362,9 @@ static int __maybe_unused stm32f7_i2c_ruint ret;if (!stm32f7_i2c_is_slave_registered (i2c_dev)) { - ret =clk_prepare_enable (i2c_dev->clk); + ret =clk_enable (i2c_dev->clk);if (ret) { -dev_err (dev,"failed to prepare_enable clock\n" ); +dev_err (dev,"failed to enable clock\n" );return ret; } }
Greg Kroah-Hartman
maintainerPATCH 490/691 i2c: qcom-geni: Use IRQF_NO_AUTOEN flag in request_irq()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit e2c85d85a05f16af2223fcc0195ff50a7938b372 upstream.
disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ.
--- drivers/i2c/busses/i2c-qcom-geni.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/i2c/busses/i2c-qcom-geni.c +1 -3
@@ -565,15 +565,13 @@ static int geni_i2c_probe(struct platforinit_completion (&gi2c->done);spin_lock_init (&gi2c->lock);platform_set_drvdata (pdev, gi2c); - ret =devm_request_irq (dev, gi2c->irq, geni_i2c_irq,0 , + ret =devm_request_irq (dev, gi2c->irq, geni_i2c_irq,IRQF_NO_AUTOEN ,dev_name (dev), gi2c);if (ret) {dev_err (dev,"Request_irq failed:%d: err:%d\n" , gi2c->irq, ret);return ret; } -/* Disable the interrupt so that the system can enter low-power mode */ -disable_irq (gi2c->irq);i2c_set_adapdata (&gi2c->adap, gi2c); gi2c->adap.dev.parent = dev; gi2c->adap.dev.of_node = dev->of_node;
Greg Kroah-Hartman
maintainerPATCH 491/691 i2c: xiic: Wait for TX empty to avoid missed TX NAKs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
commit 521da1e9225450bd323db5fa5bca942b1dc485b7 upstream.
Frequently an I2C write will be followed by a read, such as a register address write followed by a read of the register value. In this driver, when the TX FIFO half empty interrupt was raised and it was determined that there was enough space in the TX FIFO to send the following read command, it would do so without waiting for the TX FIFO to actually empty.
Unfortunately it appears that in some cases this can result in a NAK that was raised by the target device on the write, such as due to an unsupported register address, being ignored and the subsequent read being done anyway. This can potentially put the I2C bus into an invalid state and/or result in invalid read data being processed.
To avoid this, once a message has been fully written to the TX FIFO, wait for the TX FIFO empty interrupt before moving on to the next message, to ensure NAKs are handled properly.
--- drivers/i2c/busses/i2c-xiic.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/i2c/busses/i2c-xiic.c +9 -10
@@ -494,14 +494,17 @@ static irqreturn_t xiic_process(int irq, goto out; } -xiic_fill_tx_fifo (i2c); - -/* current message sent and there is space in the fifo */ -if (!xiic_tx_space (i2c) &&xiic_tx_fifo_space (i2c) >=2 ) { +if (xiic_tx_space (i2c)) { +xiic_fill_tx_fifo (i2c); + }else { +/* current message fully written */ dev_dbg (i2c->adap.dev.parent,"%s end of message sent, nmsgs: %d\n" , __func__, i2c->nmsgs); -if (i2c->nmsgs >1 ) { +/* Don't move onto the next message until the TX FIFO empties, +* to ensure that a NAK is not missed. +*/ +if (i2c->nmsgs >1 && (pend &XIIC_INTR_TX_EMPTY_MASK )) { i2c->nmsgs--; i2c->tx_msg++; xfer_more =1 ;
@@ -512,11 +515,7 @@ static irqreturn_t xiic_process(int irq,"%s Got TX IRQ but no more to do...\n" , __func__); } - }else if (!xiic_tx_space (i2c) && (i2c->nmsgs ==1 )) -/* current frame is sent and is last, -* make sure to disable tx half -*/ -xiic_irq_dis (i2c,XIIC_INTR_TX_HALF_MASK ); + } } out:dev_dbg (i2c->adap.dev.parent,"%s clr: 0x%x\n" , __func__, clr);
Greg Kroah-Hartman
maintainerPATCH 492/691 firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 9c3a62c20f7fb00294a4237e287254456ba8a48b upstream.
mbox_client_to_bpmp() is not used, W=1 builds:
drivers/firmware/tegra/bpmp.c:28:1: error: unused function 'mbox_client_to_bpmp' [-Werror,-Wunused-function]
--- drivers/firmware/tegra/bpmp.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/firmware/tegra/bpmp.c +0 -6
@@ -25,12 +25,6 @@#define MSG_RING BIT(1)#define TAG_SZ 32 -static inline struct tegra_bpmp * -mbox_client_to_bpmp (struct mbox_client *client) -{ - return container_of(client, struct tegra_bpmp, mbox.client); -} -static inline const struct tegra_bpmp_ops *channel_to_ops (struct tegra_bpmp_channel *channel) {
Greg Kroah-Hartman
maintainerPATCH 493/691 spi: bcm63xx: Fix module autoloading
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit 909f34f2462a99bf876f64c5c61c653213e32fce upstream.
Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded based on the alias from platform_device_id table.
--- drivers/spi/spi-bcm63xx.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/spi-bcm63xx.c +1 -0
@@ -476,6 +476,7 @@ static const struct platform_device_id b { }, }; +MODULE_DEVICE_TABLE (platform, bcm63xx_spi_dev_match);static const struct of_device_id bcm63xx_spi_of_match[] = { { .compatible ="brcm,bcm6348-spi" , .data = &bcm6348_spi_reg_offsets },
Greg Kroah-Hartman
maintainerPATCH 494/691 power: supply: hwmon: Fix missing temp1_max_alarm attribute
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit e50a57d16f897e45de1112eb6478577b197fab52 upstream.
Temp channel 0 aka temp1 can have a temp1_max_alarm attribute for power_supply devices which have a POWER_SUPPLY_PROP_TEMP_ALERT_MAX property.
HWMON_T_MAX_ALARM was missing from power_supply_hwmon_info for temp channel 0, causing the hwmon temp1_max_alarm attribute to be missing from such power_supply devices.
Add this to power_supply_hwmon_info to fix this.
--- drivers/power/supply/power_supply_hwmon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/power/supply/power_supply_hwmon.c +2 -1
@@ -299,7 +299,8 @@ static const struct hwmon_channel_info *HWMON_T_INPUT |HWMON_T_MAX |HWMON_T_MIN | -HWMON_T_MIN_ALARM , +HWMON_T_MIN_ALARM | +HWMON_T_MAX_ALARM ,HWMON_T_LABEL | HWMON_T_INPUT |
Greg Kroah-Hartman
maintainerPATCH 495/691 perf/core: Fix small negative period being ignored
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Gengkun <[email protected]>
commit 62c0b1061593d7012292f781f11145b2d46f43ab upstream.
In perf_adjust_period, we will first calculate period, and then use this period to calculate delta. However, when delta is less than 0, there will be a deviation compared to when delta is greater than or equal to 0. For example, when delta is in the range of [-14,-1], the range of delta = delta + 7 is between [-7,6], so the final value of delta/8 is 0. Therefore, the impact of -1 and -2 will be ignored. This is unacceptable when the target period is very short, because we will lose a lot of samples.
Here are some tests and analyzes:
before:
# perf record -e cs -F 1000 ./a.out [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.022 MB perf.data (518 samples) ]
# perf script ... a.out 396 257.956048: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.957891: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.959730: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.961545: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.963355: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.965163: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.966973: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.968785: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.970593: 23 cs: ffffffff81f4eeec schedul> ...
after:
# perf record -e cs -F 1000 ./a.out [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.058 MB perf.data (1466 samples) ]
# perf script ... a.out 395 59.338813: 11 cs: ffffffff81f4eeec schedul> a.out 395 59.339707: 12 cs: ffffffff81f4eeec schedul> a.out 395 59.340682: 13 cs: ffffffff81f4eeec schedul> a.out 395 59.341751: 13 cs: ffffffff81f4eeec schedul> a.out 395 59.342799: 12 cs: ffffffff81f4eeec schedul> a.out 395 59.343765: 11 cs: ffffffff81f4eeec schedul> a.out 395 59.344651: 11 cs: ffffffff81f4eeec schedul> a.out 395 59.345539: 12 cs: ffffffff81f4eeec schedul> a.out 395 59.346502: 13 cs: ffffffff81f4eeec schedul> ...
test.c
int main() {
for (int i = 0; i < 20000; i++)
usleep(10);
return 0;
}# time ./a.out real 0m1.583s user 0m0.040s sys 0m0.298s
The above results were tested on x86-64 qemu with KVM enabled using test.c as test program. Ideally, we should have around 1500 samples, but the previous algorithm had only about 500, whereas the modified algorithm now has about 1400. Further more, the new version shows 1 sample per 0.001s, while the previous one is 1 sample per 0.002s.This indicates that the new algorithm is more sensitive to small negative values compared to old algorithm.
--- kernel/events/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/events/core.c +5 -1
@@ -4160,7 +4160,11 @@ static void perf_adjust_period(struct pe period =perf_calculate_period (event, nsec, count); delta = (s64)(period - hwc->sample_period); - delta = (delta +7 ) /8 ;/* low pass filter */ +if (delta >=0 ) + delta +=7 ; +else + delta -=7 ; + delta /=8 ;/* low pass filter */ sample_period = hwc->sample_period + delta;
Greg Kroah-Hartman
maintainerPATCH 496/691 parisc: Fix itlb miss handler for 64-bit programs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 9542130937e9dc707dd7c6b7af73326437da2d50 upstream.
For an itlb miss when executing code above 4 Gb on ILP64 adjust the iasq/iaoq in the same way isr/ior was adjusted. This fixes signal delivery for the 64-bit static test program from
http://ftp.parisc-linux.org/src/64bit.tar.gz. Note that signals are handled by the signal trampoline code in the 64-bit VDSO which is mapped into high userspace memory region above 4GB for 64-bit processes.
--- arch/parisc/kernel/entry.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
arch/parisc/kernel/entry.S +2 -4
@@ -1071,8 +1071,7 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ STREG %r16, PT_ISR(%r29) STREG %r17, PT_IOR(%r29) -#if 0 && defined(CONFIG_64BIT) - /* Revisit when we have 64-bit code above 4Gb */ +#if defined(CONFIG_64BIT) b,n intr_save2 skip_save_ior:
@@ -1080,8 +1079,7 @@ skip_save_ior: * need to adjust iasq/iaoq here in the same way we adjusted isr/ior * above. */ - extrd,u,* %r8,PSW_W_BIT,1,%r1 - cmpib,COND(=),n 1,%r1,intr_save2 + bb,COND(>=),n %r8,PSW_W_BIT,intr_save2 LDREG PT_IASQ0(%r29), %r16 LDREG PT_IAOQ0(%r29), %r17 /* adjust iasq/iaoq */
Greg Kroah-Hartman
maintainerPATCH 497/691 drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
commit 8b0d2f61545545ab5eef923ed6e59fc3be2385e0 upstream.
FB_DAMAGE_CLIPS is a plane property for damage handling. Its UAPI should only use UAPI types. Hence replace struct drm_rect with struct drm_mode_rect in drm_atomic_plane_set_property(). Both types are identical in practice, so there's no change in behavior.
--- drivers/gpu/drm/drm_atomic_uapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_atomic_uapi.c +1 -1
@@ -603,7 +603,7 @@ static int drm_atomic_plane_set_property &state->fb_damage_clips, val,-1 , -sizeof (struct drm_rect ), +sizeof (struct drm_mode_rect ), &replaced);return ret; }else if (property == plane->scaling_filter_property) {
Greg Kroah-Hartman
maintainerPATCH 498/691 ALSA: core: add isascii() check to card ID generator
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaroslav Kysela <[email protected]>
commit d278a9de5e1837edbe57b2f1f95a104ff6c84846 upstream.
The card identifier should contain only safe ASCII characters. The isalnum() returns true also for characters for non-ASCII characters.
--- sound/core/init.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
sound/core/init.c +10 -4
@@ -660,13 +660,19 @@ int snd_card_free(struct snd_card *card) }EXPORT_SYMBOL (snd_card_free); +/* check, if the character is in the valid ASCII range */ +static inline bool safe_ascii_char (char c) +{ +return isascii (c) &&isalnum (c); +} +/* retrieve the last word of shortname or longname */ static const char *retrieve_id_from_card_name (const char *name) {const char *spos = name;while (*name) { -if (isspace (*name) &&isalnum (name[1 ])) +if (isspace (*name) &&safe_ascii_char (name[1 ])) spos = name +1 ; name++; }
@@ -693,12 +699,12 @@ static void copy_valid_id_string(struct {char *id = card->id; -while (*nid && !isalnum (*nid)) +while (*nid && !safe_ascii_char (*nid)) nid++;if (isdigit (*nid)) *id++ =isalpha (*src) ? *src :'D' ;while (*nid && (size_t )(id - card->id) <sizeof (card->id) -1 ) { -if (isalnum (*nid)) +if (safe_ascii_char (*nid)) *id++ = *nid; nid++; }
@@ -794,7 +800,7 @@ static ssize_t id_store(struct device *dfor (idx =0 ; idx < copy; idx++) { c = buf[idx]; -if (!isalnum (c) && c !='_' && c !='-' ) +if (!safe_ascii_char (c) && c !='_' && c !='-' )return -EINVAL ; }memcpy (buf1, buf, copy);
Greg Kroah-Hartman
maintainerPATCH 499/691 ALSA: usb-audio: Add delay quirk for VIVO USB-C HEADSET
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lianqin Hu <[email protected]>
commit 73385f3e0d8088b715ae8f3f66d533c482a376ab upstream.
Audio control requests that sets sampling frequency sometimes fail on this card. Adding delay between control messages eliminates that problem.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -1900,6 +1900,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_GENERIC_IMPLICIT_FB),DEVICE_FLG (0x2b53 ,0x0031 ,/* Fiero SC-01 (firmware v1.1.0) */ QUIRK_FLAG_GENERIC_IMPLICIT_FB ), +DEVICE_FLG (0x2d95 ,0x8011 ,/* VIVO USB-C HEADSET */ +QUIRK_FLAG_CTL_MSG_DELAY_1M ),DEVICE_FLG (0x2d95 ,0x8021 ,/* VIVO USB-C-XE710 HEADSET */ QUIRK_FLAG_CTL_MSG_DELAY_1M ), DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
Greg Kroah-Hartman
maintainerPATCH 500/691 ALSA: usb-audio: Add native DSD support for Luxman D-08u
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Lalinsky <[email protected]>
commit 6b0bde5d8d4078ca5feec72fd2d828f0e5cf115d upstream.
Add native DSD support for Luxman D-08u DAC, by adding the PID/VID 1852:5062. This makes DSD playback work, and also sound quality when playing PCM files is improved, crackling sounds are gone.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -1846,6 +1846,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_DISABLE_AUTOSUSPEND),DEVICE_FLG (0x17aa ,0x104d ,/* Lenovo ThinkStation P620 Internal Speaker + Front Headset */ QUIRK_FLAG_DISABLE_AUTOSUSPEND ), +DEVICE_FLG (0x1852 ,0x5062 ,/* Luxman D-08u */ +QUIRK_FLAG_ITF_USB_DSD_DAC |QUIRK_FLAG_CTL_MSG_DELAY ),DEVICE_FLG (0x1852 ,0x5065 ,/* Luxman DA-06 */ QUIRK_FLAG_ITF_USB_DSD_DAC |QUIRK_FLAG_CTL_MSG_DELAY ), DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
Greg Kroah-Hartman
maintainerPATCH 501/691 ALSA: line6: add hw monitor volume control to POD HD500X
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans P. Moller <[email protected]>
commit 703235a244e533652346844cfa42623afb36eed1 upstream.
Add hw monitor volume control for POD HD500X. This is done adding LINE6_CAP_HWMON_CTL to the capabilities
--- sound/usb/line6/podhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/line6/podhd.c +1 -1
@@ -507,7 +507,7 @@ static const struct line6_properties pod [LINE6_PODHD500X] = { .id = "PODHD500X", .name = "POD HD500X", - .capabilities =LINE6_CAP_CONTROL + .capabilities =LINE6_CAP_CONTROL |LINE6_CAP_HWMON_CTL | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 1, .ep_ctrl_r = 0x81,
Greg Kroah-Hartman
maintainerPATCH 502/691 ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ai Chao <[email protected]>
commit dee476950cbd83125655a3f49e00d63b79f6114e upstream.
The headset mic requires a fixup to be properly detected/used.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9503,6 +9503,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1849 ,0xa233 ,"Positivo Master C6300" ,ALC269_FIXUP_HEADSET_MIC ),SND_PCI_QUIRK (0x19e5 ,0x3204 ,"Huawei MACH-WX9" ,ALC256_FIXUP_HUAWEI_MACH_WX9_PINS ),SND_PCI_QUIRK (0x19e5 ,0x320f ,"Huawei WRT-WX9 " ,ALC256_FIXUP_ASUS_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x19e5 ,0x3212 ,"Huawei KLV-WX9 " ,ALC256_FIXUP_ACER_HEADSET_MIC ),SND_PCI_QUIRK (0x1b35 ,0x1235 ,"CZC B20" ,ALC269_FIXUP_CZC_B20 ),SND_PCI_QUIRK (0x1b35 ,0x1236 ,"CZC TMI" ,ALC269_FIXUP_CZC_TMI ), SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
Greg Kroah-Hartman
maintainerPATCH 503/691 ext4: no need to continue when the number of entries is 1
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
commit 1a00a393d6a7fb1e745a41edd09019bd6a0ad64c upstream.
--- fs/ext4/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/namei.c +1 -1
@@ -2047,7 +2047,7 @@ static struct ext4_dir_entry_2 *do_split split = count/2 ; hash2 = map[split].hash; - continued = hash2 == map[split -1 ].hash; + continued = split >0 ? hash2 == map[split -1 ].hash :0 ;dxtrace (printk (KERN_INFO "Split block %lu at %x, %i/%i\n" , (unsigned long )dx_get_block (frame->at), hash2, split, count-split));
Greg Kroah-Hartman
maintainerPATCH 504/691 ext4: correct encrypted dentry name hash when not casefolded
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: yao.ly <[email protected]>
commit 70dd7b573afeba9b8f8a33f2ae1e4a9a2ec8c1ec upstream.
EXT4_DIRENT_HASH and EXT4_DIRENT_MINOR_HASH will access struct ext4_dir_entry_hash followed ext4_dir_entry. But there is no ext4_dir_entry_hash followed when inode is encrypted and not casefolded
--- fs/ext4/dir.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/ext4/dir.c +11 -3
@@ -279,12 +279,20 @@ static int ext4_readdir(struct file *filstruct fscrypt_str de_name =FSTR_INIT (de->name, de->name_len); +u32 hash; +u32 minor_hash; + +if (IS_CASEFOLDED (inode)) { + hash =EXT4_DIRENT_HASH (de); + minor_hash =EXT4_DIRENT_MINOR_HASH (de); + }else { + hash =0 ; + minor_hash =0 ; + }/* Directory is encrypted */ err =fscrypt_fname_disk_to_usr (inode, -EXT4_DIRENT_HASH (de), -EXT4_DIRENT_MINOR_HASH (de), - &de_name, &fstr); + hash, minor_hash, &de_name, &fstr); de_name = fstr; fstr.len = save_len;if (err)
Greg Kroah-Hartman
maintainerPATCH 505/691 ext4: fix slab-use-after-free in ext4_split_extent_at()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit c26ab35702f8cd0cdc78f96aa5856bfb77be798f upstream.
We hit the following use-after-free:
==================================================================
BUG: KASAN: slab-use-after-free in ext4_split_extent_at+0xba8/0xcc0 Read of size 2 at addr ffff88810548ed08 by task kworker/u20:0/40 CPU: 0 PID: 40 Comm: kworker/u20:0 Not tainted 6.9.0-dirty #724 Call Trace: <TASK> kasan_report+0x93/0xc0 ext4_split_extent_at+0xba8/0xcc0 ext4_split_extent.isra.0+0x18f/0x500 ext4_split_convert_extents+0x275/0x750 ext4_ext_handle_unwritten_extents+0x73e/0x1580 ext4_ext_map_blocks+0xe20/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
Allocated by task 40: __kmalloc_noprof+0x1ac/0x480 ext4_find_extent+0xf3b/0x1e70 ext4_ext_map_blocks+0x188/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
Freed by task 40: kfree+0xf1/0x2b0 ext4_find_extent+0xa71/0x1e70 ext4_ext_insert_extent+0xa22/0x3260 ext4_split_extent_at+0x3ef/0xcc0 ext4_split_extent.isra.0+0x18f/0x500 ext4_split_convert_extents+0x275/0x750 ext4_ext_handle_unwritten_extents+0x73e/0x1580 ext4_ext_map_blocks+0xe20/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
==================================================================
The flow of issue triggering is as follows:
ext4_split_extent_at
path = *ppath ext4_ext_insert_extent(ppath)
ext4_ext_create_new_leaf(ppath)
ext4_find_extent(orig_path)
path = *orig_path read_extent_tree_block
// return -ENOMEM or -EIO
ext4_free_ext_path(path)
kfree(path)
*orig_path = NULL
a. If err is -ENOMEM:
ext4_ext_dirty(path + path->p_depth)
// path use-after-free !!!
b. If err is -EIO and we have EXT_DEBUG defined:
ext4_ext_show_leaf(path)
eh = path[depth].p_hdr
// path also use-after-free !!!
So when trying to zeroout or fix the extent length, call ext4_find_extent() to update the path.
In addition we use *ppath directly as an ext4_ext_show_leaf() input to avoid possible use-after-free when EXT_DEBUG is defined, and to avoid unnecessary path updates.
--- fs/ext4/extents.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
fs/ext4/extents.c +20 -1
@@ -3231,6 +3231,25 @@ static int ext4_split_extent_at(handle_tif (err != -ENOSPC && err != -EDQUOT ) goto out; +/* +* Update path is required because previous ext4_ext_insert_extent() +* may have freed or reallocated the path. Using EXT4_EX_NOFAIL +* guarantees that ext4_find_extent() will not return -ENOMEM, +* otherwise -ENOMEM will cause a retry in do_writepages(), and a +* WARN_ON may be triggered in ext4_da_update_reserve_space() due to +* an incorrect ee_len causing the i_reserved_data_blocks exception. +*/ + path =ext4_find_extent (inode, ee_block, ppath, + flags |EXT4_EX_NOFAIL ); +if (IS_ERR (path)) { +EXT4_ERROR_INODE (inode,"Failed split extent on %u, err %ld" , + split,PTR_ERR (path)); +return PTR_ERR (path); + } + depth =ext_depth (inode); + ex = path[depth].p_ext; + *ppath = path; +if (EXT4_EXT_MAY_ZEROOUT & split_flag) {if (split_flag & (EXT4_EXT_DATA_VALID1 |EXT4_EXT_DATA_VALID2 )) {if (split_flag &EXT4_EXT_DATA_VALID1 ) {
@@ -3283,7 +3302,7 @@ fix_extent_len:ext4_ext_dirty (handle, inode, path + path->p_depth);return err; out: -ext4_ext_show_leaf (inode, path); +ext4_ext_show_leaf (inode, *ppath);return err; }
Greg Kroah-Hartman
maintainerPATCH 506/691 ext4: propagate errors from ext4_find_extent() in ext4_insert_range()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 369c944ed1d7c3fb7b35f24e4735761153afe7b3 upstream.
Even though ext4_find_extent() returns an error, ext4_insert_range() still returns 0. This may confuse the user as to why fallocate returns success, but the contents of the file are not as expected. So propagate the error returned by ext4_find_extent() to avoid inconsistencies.
--- fs/ext4/extents.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/extents.c +1 -0
@@ -5574,6 +5574,7 @@ static int ext4_insert_range(struct file path =ext4_find_extent (inode, offset_lblk,NULL ,0 );if (IS_ERR (path)) {up_write (&EXT4_I (inode)->i_data_sem); + ret =PTR_ERR (path); goto out_stop; }
Greg Kroah-Hartman
maintainerPATCH 507/691 ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 972090651ee15e51abfb2160e986fa050cfc7a40 upstream.
Function __jbd2_log_wait_for_space() assumes that '0' is not a valid value for transaction IDs, which is incorrect. Don't assume that and invoke jbd2_log_wait_commit() if the journal had a committing transaction instead.
--- fs/jbd2/checkpoint.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/jbd2/checkpoint.c +5 -2
@@ -91,9 +91,12 @@ __releases(&journal->j_state_lock)if (space_left < nblocks) {int chkpt = journal->j_checkpoint_transactions !=NULL ;tid_t tid =0 ; +bool has_transaction = false; -if (journal->j_committing_transaction) +if (journal->j_committing_transaction) { tid = journal->j_committing_transaction->t_tid; + has_transaction = true; + }spin_unlock (&journal->j_list_lock);write_unlock (&journal->j_state_lock);if (chkpt) {
@@ -104,7 +107,7 @@ __releases(&journal->j_state_lock)* journal was aborted due to an error. */ ; - }else if (tid) { + }else if (has_transaction) {/* * jbd2_journal_commit_transaction() may want * to take the checkpoint_mutex if JBD2_FLUSHED
Greg Kroah-Hartman
maintainerPATCH 508/691 ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 5c0f4cc84d3a601c99bc5e6e6eb1cbda542cce95 upstream.
When calling ext4_force_split_extent_at() in ext4_ext_replay_update_ex(), the 'ppath' is updated but it is the 'path' that is freed, thus potentially triggering a double-free in the following process:
ext4_ext_replay_update_ex
ppath = path
ext4_force_split_extent_at(&ppath)
ext4_split_extent_at
ext4_ext_insert_extent
ext4_ext_create_new_leaf
ext4_ext_grow_indepth
ext4_find_extent
if (depth > path[0].p_maxdepth)
kfree(path) ---> path First freed
*orig_path = path = NULL ---> null ppathkfree(path) ---> path double-free !!!
So drop the unnecessary ppath and use path directly to avoid this problem. And use ext4_find_extent() directly to update path, avoiding unnecessary memory allocation and freeing. Also, propagate the error returned by ext4_find_extent() instead of using strange error codes.
--- fs/ext4/extents.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
fs/ext4/extents.c +10 -11
@@ -5935,7 +5935,7 @@ out:int ext4_ext_replay_update_ex (struct inode *inode,ext4_lblk_t start,int len,int unwritten,ext4_fsblk_t pblk) { -struct ext4_ext_path *path =NULL , *ppath; +struct ext4_ext_path *path;struct ext4_extent *ex;int ret;
@@ -5951,30 +5951,29 @@ int ext4_ext_replay_update_ex(struct inoif (le32_to_cpu (ex->ee_block) != start ||ext4_ext_get_actual_len (ex) != len) {/* We need to split this extent to match our extent first */ - ppath = path;down_write (&EXT4_I (inode)->i_data_sem); - ret =ext4_force_split_extent_at (NULL , inode, &ppath, start,1 ); + ret =ext4_force_split_extent_at (NULL , inode, &path, start,1 );up_write (&EXT4_I (inode)->i_data_sem);if (ret) goto out; -kfree (path); - path =ext4_find_extent (inode, start,NULL ,0 ); + + path =ext4_find_extent (inode, start, &path,0 );if (IS_ERR (path)) -return -1 ; - ppath = path; +return PTR_ERR (path); ex = path[path->p_depth].p_ext;WARN_ON (le32_to_cpu (ex->ee_block) != start); +if (ext4_ext_get_actual_len (ex) != len) {down_write (&EXT4_I (inode)->i_data_sem); - ret =ext4_force_split_extent_at (NULL , inode, &ppath, + ret =ext4_force_split_extent_at (NULL , inode, &path, start + len,1 );up_write (&EXT4_I (inode)->i_data_sem);if (ret) goto out; -kfree (path); - path =ext4_find_extent (inode, start,NULL ,0 ); + + path =ext4_find_extent (inode, start, &path,0 );if (IS_ERR (path)) -return -EINVAL ; +return PTR_ERR (path); ex = path[path->p_depth].p_ext; } }
Greg Kroah-Hartman
maintainerPATCH 509/691 ext4: aovid use-after-free in ext4_ext_insert_extent()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit a164f3a432aae62ca23d03e6d926b122ee5b860d upstream.
As Ojaswin mentioned in Link, in ext4_ext_insert_extent(), if the path is reallocated in ext4_ext_create_new_leaf(), we'll use the stale path and cause UAF. Below is a sample trace with dummy values:
ext4_ext_insert_extent
path = *ppath = 2000
ext4_ext_create_new_leaf(ppath)
ext4_find_extent(ppath)
path = *ppath = 2000
if (depth > path[0].p_maxdepth)
kfree(path = 2000);
*ppath = path = NULL;
path = kcalloc() = 3000
*ppath = 3000;
return path; /* here path is still 2000, UAF! */
eh = path[depth].p_hdr
==================================================================
BUG: KASAN: slab-use-after-free in ext4_ext_insert_extent+0x26d4/0x3330 Read of size 8 at addr ffff8881027bf7d0 by task kworker/u36:1/179 CPU: 3 UID: 0 PID: 179 Comm: kworker/u6:1 Not tainted 6.11.0-rc2-dirty #866 Call Trace: <TASK> ext4_ext_insert_extent+0x26d4/0x3330 ext4_ext_map_blocks+0xe22/0x2d40 ext4_map_blocks+0x71e/0x1700 ext4_do_writepages+0x1290/0x2800
[...]
Allocated by task 179: ext4_find_extent+0x81c/0x1f70 ext4_ext_map_blocks+0x146/0x2d40 ext4_map_blocks+0x71e/0x1700 ext4_do_writepages+0x1290/0x2800 ext4_writepages+0x26d/0x4e0 do_writepages+0x175/0x700
[...]
Freed by task 179: kfree+0xcb/0x240 ext4_find_extent+0x7c0/0x1f70 ext4_ext_insert_extent+0xa26/0x3330 ext4_ext_map_blocks+0xe22/0x2d40 ext4_map_blocks+0x71e/0x1700 ext4_do_writepages+0x1290/0x2800 ext4_writepages+0x26d/0x4e0 do_writepages+0x175/0x700
[...]
==================================================================
So use *ppath to update the path to avoid the above problem.
--- fs/ext4/extents.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/extents.c +1 -0
@@ -2100,6 +2100,7 @@ prepend: ppath, newext);if (err) goto cleanup; + path = *ppath; depth =ext_depth (inode); eh = path[depth].p_hdr;
Greg Kroah-Hartman
maintainerPATCH 510/691 ext4: fix double brelse() the buffer of the extents path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit dcaa6c31134c0f515600111c38ed7750003e1b9c upstream.
In ext4_ext_try_to_merge_up(), set path[1].p_bh to NULL after it has been released, otherwise it may be released twice. An example of what triggers this is as follows:
split2 map split1
|--------|-------|--------|
ext4_ext_map_blocks
ext4_ext_handle_unwritten_extents
ext4_split_convert_extents
// path->p_depth == 0
ext4_split_extent
// 1. do split1
ext4_split_extent_at
|ext4_ext_insert_extent
| ext4_ext_create_new_leaf
| ext4_ext_grow_indepth
| le16_add_cpu(&neh->eh_depth, 1)
| ext4_find_extent
| // return -ENOMEM
|// get error and try zeroout
|path = ext4_find_extent
| path->p_depth = 1
|ext4_ext_try_to_merge
| ext4_ext_try_to_merge_up
| path->p_depth = 0
| brelse(path[1].p_bh) ---> not set to NULL here
|// zeroout success
// 2. update path
ext4_find_extent
// 3. do split2
ext4_split_extent_at
ext4_ext_insert_extent
ext4_ext_create_new_leaf
ext4_ext_grow_indepth
le16_add_cpu(&neh->eh_depth, 1)
ext4_find_extent
path[0].p_bh = NULL;
path->p_depth = 1
read_extent_tree_block ---> return err
// path[1].p_bh is still the old value
ext4_free_ext_path
ext4_ext_drop_refs
// path->p_depth == 1
brelse(path[1].p_bh) ---> brelse a buffer twiceFinally got the following WARRNING when removing the buffer from lru:
============================================
VFS: brelse: Trying to free free buffer
WARNING: CPU: 2 PID: 72 at fs/buffer.c:1241 __brelse+0x58/0x90 CPU: 2 PID: 72 Comm: kworker/u19:1 Not tainted 6.9.0-dirty #716 RIP: 0010:__brelse+0x58/0x90 Call Trace: <TASK> __find_get_block+0x6e7/0x810 bdev_getblk+0x2b/0x480 __ext4_get_inode_loc+0x48a/0x1240 ext4_get_inode_loc+0xb2/0x150 ext4_reserve_inode_write+0xb7/0x230 __ext4_mark_inode_dirty+0x144/0x6a0 ext4_ext_insert_extent+0x9c8/0x3230 ext4_ext_map_blocks+0xf45/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
============================================
--- fs/ext4/extents.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/extents.c +1 -0
@@ -1872,6 +1872,7 @@ static void ext4_ext_try_to_merge_up(han path[0 ].p_hdr->eh_max =cpu_to_le16 (max_root);brelse (path[1 ].p_bh); + path[1 ].p_bh =NULL ;ext4_free_blocks (handle, inode,NULL , blk,1 ,EXT4_FREE_BLOCKS_METADATA |EXT4_FREE_BLOCKS_FORGET ); }
Greg Kroah-Hartman
maintainerPATCH 511/691 ext4: update orig_path in ext4_find_extent()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 5b4b2dcace35f618fe361a87bae6f0d13af31bc1 upstream.
In ext4_find_extent(), if the path is not big enough, we free it and set *orig_path to NULL. But after reallocating and successfully initializing the path, we don't update *orig_path, in which case the caller gets a valid path but a NULL ppath, and this may cause a NULL pointer dereference or a path memory leak. For example:
ext4_split_extent
path = *ppath = 2000
ext4_find_extent
if (depth > path[0].p_maxdepth)
kfree(path = 2000);
*orig_path = path = NULL;
path = kcalloc() = 3000
ext4_split_extent_at(*ppath = NULL)
path = *ppath;
ex = path[depth].p_ext;
// NULL pointer dereference!==================================================================
BUG: kernel NULL pointer dereference, address: 0000000000000010 CPU: 6 UID: 0 PID: 576 Comm: fsstress Not tainted 6.11.0-rc2-dirty #847 RIP: 0010:ext4_split_extent_at+0x6d/0x560 Call Trace: <TASK> ext4_split_extent.isra.0+0xcb/0x1b0 ext4_ext_convert_to_initialized+0x168/0x6c0 ext4_ext_handle_unwritten_extents+0x325/0x4d0 ext4_ext_map_blocks+0x520/0xdb0 ext4_map_blocks+0x2b0/0x690 ext4_iomap_begin+0x20e/0x2c0
[...]
==================================================================
Therefore, *orig_path is updated when the extent lookup succeeds, so that the caller can safely use path or *ppath.
--- fs/ext4/extents.c | 3 ++- fs/ext4/move_extent.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-)
fs/ext4/extents.c +2 -1
@@ -950,6 +950,8 @@ ext4_find_extent(struct inode *inode, exext4_ext_show_path (inode, path); +if (orig_path) + *orig_path = path;return path; err:
@@ -3250,7 +3252,6 @@ static int ext4_split_extent_at(handle_t } depth =ext_depth (inode); ex = path[depth].p_ext; - *ppath = path;if (EXT4_EXT_MAY_ZEROOUT & split_flag) {if (split_flag & (EXT4_EXT_DATA_VALID1 |EXT4_EXT_DATA_VALID2 )) {
fs/ext4/move_extent.c +0 -1
@@ -36,7 +36,6 @@ get_ext_path(struct inode *inode, ext4_l *ppath =NULL ;return -ENODATA ; } - *ppath = path;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 512/691 ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit dd589b0f1445e1ea1085b98edca6e4d5dedb98d0 upstream.
Function ext4_wait_for_tail_page_commit() assumes that '0' is not a valid value for transaction IDs, which is incorrect. Don't assume that and invoke jbd2_log_wait_commit() if the journal had a committing transaction instead.
--- fs/ext4/inode.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/ext4/inode.c +7 -4
@@ -5301,8 +5301,9 @@ static void ext4_wait_for_tail_page_commstruct page *page;unsigned offset;journal_t *journal =EXT4_SB (inode->i_sb)->s_journal; -tid_t commit_tid =0 ; +tid_t commit_tid;int ret; +bool has_transaction; offset = inode->i_size & (PAGE_SIZE -1 );/*
@@ -5327,12 +5328,14 @@ static void ext4_wait_for_tail_page_commput_page (page);if (ret != -EBUSY )return ; - commit_tid =0 ; + has_transaction = false;read_lock (&journal->j_state_lock); -if (journal->j_committing_transaction) +if (journal->j_committing_transaction) { commit_tid = journal->j_committing_transaction->t_tid; + has_transaction = true; + }read_unlock (&journal->j_state_lock); -if (commit_tid) +if (has_transaction)jbd2_log_wait_commit (journal, commit_tid); } }
Greg Kroah-Hartman
maintainerPATCH 513/691 ext4: fix incorrect tid assumption in jbd2_journal_shrink_checkpoint_list()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 7a6443e1dad70281f99f0bd394d7fd342481a632 upstream.
Function jbd2_journal_shrink_checkpoint_list() assumes that '0' is not a valid value for transaction IDs, which is incorrect. Don't assume that and use two extra boolean variables to control the loop iterations and keep track of the first and last tid.
--- fs/jbd2/checkpoint.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/jbd2/checkpoint.c +5 -2
@@ -427,6 +427,7 @@ unsigned long jbd2_journal_shrink_checkptid_t tid =0 ;unsigned long nr_freed =0 ;unsigned long freed; +bool first_set = false; again:spin_lock (&journal->j_list_lock);
@@ -446,8 +447,10 @@ again:else transaction = journal->j_checkpoint_transactions; -if (!first_tid) +if (!first_set) { first_tid = transaction->t_tid; + first_set = true; + } last_transaction = journal->j_checkpoint_transactions->t_cpprev; next_transaction = transaction; last_tid = last_transaction->t_tid;
@@ -477,7 +480,7 @@ again:spin_unlock (&journal->j_list_lock);cond_resched (); -if (*nr_to_scan && next_tid) +if (*nr_to_scan && journal->j_shrink_transaction) goto again; out: trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid,
Greg Kroah-Hartman
maintainerPATCH 514/691 ext4: fix fast commit inode enqueueing during a full journal commit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 6db3c1575a750fd417a70e0178bdf6efa0dd5037 upstream.
When a full journal commit is on-going, any fast commit has to be enqueued into a different queue: FC_Q_STAGING instead of FC_Q_MAIN. This enqueueing is done only once, i.e. if an inode is already queued in a previous fast commit entry it won't be enqueued again. However, if a full commit starts _after_ the inode is enqueued into FC_Q_MAIN, the next fast commit needs to be done into FC_Q_STAGING. And this is not being done in function ext4_fc_track_template().
This patch fixes the issue by re-enqueuing an inode into the STAGING queue during the fast commit clean-up callback when doing a full commit. However, to prevent a race with a fast-commit, the clean-up callback has to be called with the journal locked.
This bug was found using fstest generic/047. This test creates several 32k bytes files, sync'ing each of them after it's creation, and then shutting down the filesystem. Some data may be loss in this operation; for example a file may have it's size truncated to zero.
--- fs/ext4/fast_commit.c | 15 ++++++++++++++- fs/jbd2/journal.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-)
fs/ext4/fast_commit.c +14 -1
@@ -1278,8 +1278,21 @@ static void ext4_fc_cleanup(journal_t *jlist_del_init (&iter->i_fc_list);ext4_clear_inode_state (&iter->vfs_inode,EXT4_STATE_FC_COMMITTING ); -if (tid_geq (tid, iter->i_sync_tid)) +if (tid_geq (tid, iter->i_sync_tid)) {ext4_fc_reset_inode (&iter->vfs_inode); + }else if (full) { +/* +* We are called after a full commit, inode has been +* modified while the commit was running. Re-enqueue +* the inode into STAGING, which will then be splice +* back into MAIN. This cannot happen during +* fastcommit because the journal is locked all the +* time in that case (and tid doesn't increase so +* tid check above isn't reliable). +*/ +list_add_tail (&EXT4_I (&iter->vfs_inode)->i_fc_list, + &sbi->s_fc_q[FC_Q_STAGING ]); + }/* Make sure EXT4_STATE_FC_COMMITTING bit is clear */ smp_mb ();#if (BITS_PER_LONG <64 )
fs/jbd2/journal.c +1 -1
@@ -770,9 +770,9 @@ EXPORT_SYMBOL(jbd2_fc_begin_commit);*/ static int __jbd2_fc_end_commit (journal_t *journal,tid_t tid,bool fallback) { -jbd2_journal_unlock_updates (journal);if (journal->j_fc_cleanup_callback) journal->j_fc_cleanup_callback (journal,0 , tid); +jbd2_journal_unlock_updates (journal);write_lock (&journal->j_state_lock); journal->j_flags &= ~JBD2_FAST_COMMIT_ONGOING ;if (fallback)
Greg Kroah-Hartman
maintainerPATCH 515/691 ext4: use handle to mark fc as ineligible in __track_dentry_update()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit faab35a0370fd6e0821c7a8dd213492946fc776f upstream.
Calling ext4_fc_mark_ineligible() with a NULL handle is racy and may result in a fast-commit being done before the filesystem is effectively marked as ineligible. This patch fixes the calls to this function in __track_dentry_update() by adding an extra parameter to the callback used in ext4_fc_track_template().
--- fs/ext4/fast_commit.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
fs/ext4/fast_commit.c +11 -8
@@ -344,7 +344,7 @@ void ext4_fc_mark_ineligible(struct supe*/ static int ext4_fc_track_template (handle_t *handle,struct inode *inode, -int (*__fc_track_fn)(struct inode *,void *,bool ), +int (*__fc_track_fn)(handle_t *handle,struct inode *,void *,bool ),void *args,int enqueue) {bool update = false;
@@ -361,7 +361,7 @@ static int ext4_fc_track_template(ext4_fc_reset_inode (inode); ei->i_sync_tid = tid; } - ret =__fc_track_fn (inode, args, update); + ret =__fc_track_fn (handle, inode, args, update);mutex_unlock (&ei->i_fc_lock);if (!enqueue)
@@ -385,7 +385,8 @@ struct __track_dentry_update_args { };/* __track_fn for directory entry updates. Called with ei->i_fc_lock. */ -static int __track_dentry_update (struct inode *inode,void *arg,bool update) +static int __track_dentry_update (handle_t *handle,struct inode *inode, +void *arg,bool update) {struct ext4_fc_dentry_update *node;struct ext4_inode_info *ei =EXT4_I (inode);
@@ -400,14 +401,14 @@ static int __track_dentry_update(structif (IS_ENCRYPTED (dir)) {ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_ENCRYPTED_FILENAME , -NULL ); + handle);mutex_lock (&ei->i_fc_lock);return -EOPNOTSUPP ; } node =kmem_cache_alloc (ext4_fc_dentry_cachep,GFP_NOFS );if (!node) { -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM ,NULL ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM , handle);mutex_lock (&ei->i_fc_lock);return -ENOMEM ; }
@@ -419,7 +420,7 @@ static int __track_dentry_update(struct node->fcd_name.name =kmalloc (dentry->d_name.len,GFP_NOFS );if (!node->fcd_name.name) {kmem_cache_free (ext4_fc_dentry_cachep, node); -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM ,NULL ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM , handle);mutex_lock (&ei->i_fc_lock);return -ENOMEM ; }
@@ -533,7 +534,8 @@ void ext4_fc_track_create(handle_t *hand }/* __track_fn for inode tracking */ -static int __track_inode (struct inode *inode,void *arg,bool update) +static int __track_inode (handle_t *handle,struct inode *inode,void *arg, +bool update) {if (update)return -EEXIST ;
@@ -573,7 +575,8 @@ struct __track_range_args { };/* __track_fn for tracking data updates */ -static int __track_range (struct inode *inode,void *arg,bool update) +static int __track_range (handle_t *handle,struct inode *inode,void *arg, +bool update) {struct ext4_inode_info *ei =EXT4_I (inode);ext4_lblk_t oldstart;
Greg Kroah-Hartman
maintainerPATCH 516/691 ext4: mark fc as ineligible using an handle in ext4_xattr_set()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 04e6ce8f06d161399e5afde3df5dcfa9455b4952 upstream.
Calling ext4_fc_mark_ineligible() with a NULL handle is racy and may result in a fast-commit being done before the filesystem is effectively marked as ineligible. This patch moves the call to this function so that an handle can be used. If a transaction fails to start, then there's not point in trying to mark the filesystem as ineligible, and an error will eventually be returned to user-space.
--- fs/ext4/xattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/xattr.c +2 -1
@@ -2512,6 +2512,8 @@ retry: error =ext4_xattr_set_handle (handle, inode, name_index, name, value, value_len, flags); +ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR , + handle); error2 =ext4_journal_stop (handle);if (error == -ENOSPC &&ext4_should_retry_alloc (sb, &retries))
@@ -2519,7 +2521,6 @@ retry:if (error ==0 ) error = error2; } -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR ,NULL );return error; }
Greg Kroah-Hartman
maintainerPATCH 517/691 riscv: define ILLEGAL_POINTER_VALUE for 64bit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
commit 5c178472af247c7b50f962495bb7462ba453b9fb upstream.
This is used in poison.h for poison pointer offset. Based on current SV39, SV48 and SV57 vm layout, 0xdead000000000000 is a proper value that is not mappable, this can avoid potentially turning an oops to an expolit.
--- arch/riscv/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
arch/riscv/Kconfig +5 -0
@@ -210,6 +210,11 @@ config GENERIC_HWEIGHT config FIX_EARLYCON_MEM def_bool MMU +config ILLEGAL_POINTER_VALUE + hex + default 0 if 32BIT + default 0xdead000000000000 if 64BIT + config PGTABLE_LEVELS int default 3 if 64BIT
Greg Kroah-Hartman
maintainerPATCH 518/691 exfat: fix memory leak in exfat_load_bitmap()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuezhang Mo <[email protected]>
commit d2b537b3e533f28e0d97293fe9293161fe8cd137 upstream.
If the first directory entry in the root directory is not a bitmap directory entry, 'bh' will not be released and reassigned, which will cause a memory leak.
--- fs/exfat/balloc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/exfat/balloc.c +5 -5
@@ -110,11 +110,8 @@ int exfat_load_bitmap(struct super_blockreturn -EIO ; type =exfat_get_entry_type (ep); -if (type ==TYPE_UNUSED ) -break ; -if (type !=TYPE_BITMAP ) -continue ; -if (ep->dentry.bitmap.flags ==0x0 ) { +if (type ==TYPE_BITMAP && + ep->dentry.bitmap.flags ==0x0 ) {int err; err =exfat_allocate_bitmap (sb, ep);
@@ -122,6 +119,9 @@ int exfat_load_bitmap(struct super_blockreturn err; }brelse (bh); + +if (type ==TYPE_UNUSED ) +return -EINVAL ; }if (exfat_get_next_cluster (sb, &clu.dir))
Greg Kroah-Hartman
maintainerPATCH 519/691 perf hist: Update hist symbol when updating maps
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Fleming <[email protected]>
commit ac01c8c4246546fd8340a232f3ada1921dc0ee48 upstream.
AddressSanitizer found a use-after-free bug in the symbol code which manifested as 'perf top' segfaulting.
==1238389==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b00c48844b at pc 0x5650d8035961 bp 0x7f751aaecc90 sp 0x7f751aaecc80 READ of size 1 at 0x60b00c48844b thread T193
#0 0x5650d8035960 in _sort__sym_cmp util/sort.c:310
#1 0x5650d8043744 in hist_entry__cmp util/hist.c:1286
#2 0x5650d8043951 in hists__findnew_entry util/hist.c:614
#3 0x5650d804568f in __hists__add_entry util/hist.c:754
#4 0x5650d8045bf9 in hists__add_entry util/hist.c:772
#5 0x5650d8045df1 in iter_add_single_normal_entry util/hist.c:997
#6 0x5650d8043326 in hist_entry_iter__add util/hist.c:1242
#7 0x5650d7ceeefe in perf_event__process_sample /home/matt/src/linux/tools/perf/builtin-top.c:845
#8 0x5650d7ceeefe in deliver_event /home/matt/src/linux/tools/perf/builtin-top.c:1208
#9 0x5650d7fdb51b in do_flush util/ordered-events.c:245
#10 0x5650d7fdb51b in __ordered_events__flush util/ordered-events.c:324
#11 0x5650d7ced743 in process_thread /home/matt/src/linux/tools/perf/builtin-top.c:1120
#12 0x7f757ef1f133 in start_thread nptl/pthread_create.c:442
#13 0x7f757ef9f7db in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81When updating hist maps it's also necessary to update the hist symbol reference because the old one gets freed in map__put().
While this bug was probably introduced with 5c24b67aae72f54c ("perf
tools: Replace map->referenced & maps->removed_maps with map->refcnt"), the symbol objects were leaked until c087e9480cf33672 ("perf machine:
Fix refcount usage when processing PERF_RECORD_KSYMBOL") was merged so the bug was masked.
--- tools/perf/util/hist.c | 5 +++++ 1 file changed, 5 insertions(+)
tools/perf/util/hist.c +5 -0
@@ -629,6 +629,11 @@ static struct hist_entry *hists__findnew* the history counter to increment. */ if (he->ms.map != entry->ms.map) { +if (he->ms.sym) { +u64 addr = he->ms.sym->start; + he->ms.sym =map__find_symbol (entry->ms.map, addr); + } +map__put (he->ms.map); he->ms.map =map__get (entry->ms.map); }
Greg Kroah-Hartman
maintainerPATCH 520/691 nfsd: fix delegation_blocked() to block correctly for at least 30 seconds
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 45bb63ed20e02ae146336412889fe5450316a84f upstream.
The pair of bloom filtered used by delegation_blocked() was intended to block delegations on given filehandles for between 30 and 60 seconds. A new filehandle would be recorded in the "new" bit set. That would then be switch to the "old" bit set between 0 and 30 seconds later, and it would remain as the "old" bit set for 30 seconds.
Unfortunately the code intended to clear the old bit set once it reached 30 seconds old, preparing it to be the next new bit set, instead cleared the *new* bit set before switching it to be the old bit set. This means that the "old" bit set is always empty and delegations are blocked between 0 and 30 seconds.
This patch updates bd->new before clearing the set with that index, instead of afterwards.
--- fs/nfsd/nfs4state.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/nfsd/nfs4state.c +3 -2
@@ -1090,7 +1090,8 @@ static void nfs4_free_deleg(struct nfs4_* When a delegation is recalled, the filehandle is stored in the "new" * filter. * Every 30 seconds we swap the filters and clear the "new" one, -* unless both are empty of course. +* unless both are empty of course. This results in delegations for a +* given filehandle being blocked for between 30 and 60 seconds. * * Each filter is 256 bits. We hash the filehandle to 32bit and use the * low 3 bytes as hash-table indices.
@@ -1119,9 +1120,9 @@ static int delegation_blocked(struct knfif (ktime_get_seconds () - bd->swap_time >30 ) { bd->entries -= bd->old_entries; bd->old_entries = bd->entries; + bd->new =1 -bd->new;memset (bd->set[bd->new],0 ,sizeof (bd->set[0 ])); - bd->new =1 -bd->new; bd->swap_time =ktime_get_seconds (); }spin_unlock (&blocked_delegations_lock);
Greg Kroah-Hartman
maintainerPATCH 521/691 nfsd: map the EBADMSG to nfserr_io to avoid warning
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
commit 340e61e44c1d2a15c42ec72ade9195ad525fd048 upstream.
Ext4 will throw -EBADMSG through ext4_readdir when a checksum error occurs, resulting in the following WARNING.
Fix it by mapping EBADMSG to nfserr_io.
nfsd_buffered_readdir
iterate_dir // -EBADMSG -74
ext4_readdir // .iterate_shared
ext4_dx_readdir
ext4_htree_fill_tree
htree_dirblock_to_tree
ext4_read_dirblock
__ext4_read_dirblock
ext4_dirblock_csum_verify
warn_no_space_for_csum
__warn_no_space_for_csum
return ERR_PTR(-EFSBADCRC) // -EBADMSG -74
nfserrno // WARNING
[ 161.115610] ------------[ cut here ]------------ [ 161.116465] nfsd: non-standard errno: -74 [ 161.117315] WARNING: CPU: 1 PID: 780 at fs/nfsd/nfsproc.c:878 nfserrno+0x9d/0xd0 [ 161.118596] Modules linked in: [ 161.119243] CPU: 1 PID: 780 Comm: nfsd Not tainted 5.10.0-00014-g79679361fd5d #138 [ 161.120684] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qe mu.org 04/01/2014 [ 161.123601] RIP: 0010:nfserrno+0x9d/0xd0 [ 161.124676] Code: 0f 87 da 30 dd 00 83 e3 01 b8 00 00 00 05 75 d7 44 89 ee 48 c7 c7 c0 57 24 98 89 44 24 04 c6 05 ce 2b 61 03 01 e8 99 20 d8 00 <0f> 0b 8b 44 24 04 eb b5 4c 89 e6 48 c7 c7 a0 6d a4 99 e8 cc 15 33 [ 161.127797] RSP: 0018:ffffc90000e2f9c0 EFLAGS: 00010286 [ 161.128794] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 161.130089] RDX: 1ffff1103ee16f6d RSI: 0000000000000008 RDI: fffff520001c5f2a [ 161.131379] RBP: 0000000000000022 R08: 0000000000000001 R09: ffff8881f70c1827 [ 161.132664] R10: ffffed103ee18304 R11: 0000000000000001 R12: 0000000000000021 [ 161.133949] R13: 00000000ffffffb6 R14: ffff8881317c0000 R15: ffffc90000e2fbd8 [ 161.135244] FS: 0000000000000000(0000) GS:ffff8881f7080000(0000) knlGS:0000000000000000 [ 161.136695] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 161.137761] CR2: 00007fcaad70b348 CR3: 0000000144256006 CR4: 0000000000770ee0 [ 161.139041] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 161.140291] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 161.141519] PKRU: 55555554 [ 161.142076] Call Trace: [ 161.142575] ? __warn+0x9b/0x140 [ 161.143229] ? nfserrno+0x9d/0xd0 [ 161.143872] ? report_bug+0x125/0x150 [ 161.144595] ? handle_bug+0x41/0x90 [ 161.145284] ? exc_invalid_op+0x14/0x70 [ 161.146009] ? asm_exc_invalid_op+0x12/0x20 [ 161.146816] ? nfserrno+0x9d/0xd0 [ 161.147487] nfsd_buffered_readdir+0x28b/0x2b0 [ 161.148333] ? nfsd4_encode_dirent_fattr+0x380/0x380 [ 161.149258] ? nfsd_buffered_filldir+0xf0/0xf0 [ 161.150093] ? wait_for_concurrent_writes+0x170/0x170 [ 161.151004] ? generic_file_llseek_size+0x48/0x160 [ 161.151895] nfsd_readdir+0x132/0x190 [ 161.152606] ? nfsd4_encode_dirent_fattr+0x380/0x380 [ 161.153516] ? nfsd_unlink+0x380/0x380 [ 161.154256] ? override_creds+0x45/0x60 [ 161.155006] nfsd4_encode_readdir+0x21a/0x3d0 [ 161.155850] ? nfsd4_encode_readlink+0x210/0x210 [ 161.156731] ? write_bytes_to_xdr_buf+0x97/0xe0 [ 161.157598] ? __write_bytes_to_xdr_buf+0xd0/0xd0 [ 161.158494] ? lock_downgrade+0x90/0x90 [ 161.159232] ? nfs4svc_decode_voidarg+0x10/0x10 [ 161.160092] nfsd4_encode_operation+0x15a/0x440 [ 161.160959] nfsd4_proc_compound+0x718/0xe90 [ 161.161818] nfsd_dispatch+0x18e/0x2c0 [ 161.162586] svc_process_common+0x786/0xc50 [ 161.163403] ? nfsd_svc+0x380/0x380 [ 161.164137] ? svc_printk+0x160/0x160 [ 161.164846] ? svc_xprt_do_enqueue.part.0+0x365/0x380 [ 161.165808] ? nfsd_svc+0x380/0x380 [ 161.166523] ? rcu_is_watching+0x23/0x40 [ 161.167309] svc_process+0x1a5/0x200 [ 161.168019] nfsd+0x1f5/0x380 [ 161.168663] ? nfsd_shutdown_threads+0x260/0x260 [ 161.169554] kthread+0x1c4/0x210 [ 161.170224] ? kthread_insert_work_sanity_check+0x80/0x80 [ 161.171246] ret_from_fork+0x1f/0x30
--- fs/nfsd/vfs.c | 1 + 1 file changed, 1 insertion(+)
fs/nfsd/vfs.c +1 -0
@@ -100,6 +100,7 @@ nfserrno (int errno) { nfserr_io, -EUCLEAN }, { nfserr_perm, -ENOKEY }, { nfserr_no_grace, -ENOGRACE}, + { nfserr_io, -EBADMSG }, };int i;
Greg Kroah-Hartman
maintainerPATCH 522/691 NFSD: Fix NFSv4s PUTPUBFH operation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
commit 202f39039a11402dcbcd5fece8d9fa6be83f49ae upstream.
According to RFC 8881, all minor versions of NFSv4 support PUTPUBFH.
Replace the XDR decoder for PUTPUBFH with a "noop" since we no longer want the minorversion check, and PUTPUBFH has no arguments to decode. (Ideally nfsd4_decode_noop should really be called nfsd4_decode_void).
PUTPUBFH should now behave just like PUTROOTFH.
--- fs/nfsd/nfs4xdr.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
fs/nfsd/nfs4xdr.c +1 -9
@@ -1246,14 +1246,6 @@ nfsd4_decode_putfh(struct nfsd4_compound }static __be32 -nfsd4_decode_putpubfh (struct nfsd4_compoundargs *argp,union nfsd4_op_u *p) -{ -if (argp->minorversion ==0 ) -return nfs_ok; -return nfserr_notsupp; -} - -static __be32 nfsd4_decode_read (struct nfsd4_compoundargs *argp,union nfsd4_op_u *u) {struct nfsd4_read *read = &u->read;
@@ -2345,7 +2337,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = [OP_OPEN_CONFIRM] = nfsd4_decode_open_confirm, [OP_OPEN_DOWNGRADE] = nfsd4_decode_open_downgrade, [OP_PUTFH] = nfsd4_decode_putfh, - [OP_PUTPUBFH] = nfsd4_decode_putpubfh, + [OP_PUTPUBFH] = nfsd4_decode_noop, [OP_PUTROOTFH] = nfsd4_decode_noop, [OP_READ] = nfsd4_decode_read, [OP_READDIR] = nfsd4_decode_readdir,
Greg Kroah-Hartman
maintainerPATCH 523/691 aoe: fix the potential use-after-free problem in more places
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chun-Yi Lee <[email protected]>
commit 6d6e54fc71ad1ab0a87047fd9c211e75d86084a3 upstream.
For fixing CVE-2023-6270, f98364e92662 ("aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts") makes tx() calling dev_put() instead of doing in aoecmd_cfg_pkts(). It avoids that the tx() runs into use-after-free.
Then Nicolai Stange found more places in aoe have potential use-after-free problem with tx(). e.g. revalidate(), aoecmd_ata_rw(), resend(), probe() and aoecmd_cfg_rsp(). Those functions also use aoenet_xmit() to push packet to tx queue. So they should also use dev_hold() to increase the refcnt of skb->dev.
On the other hand, moving dev_put() to tx() causes that the refcnt of skb->dev be reduced to a negative value, because corresponding dev_hold() are not called in revalidate(), aoecmd_ata_rw(), resend(), probe(), and aoecmd_cfg_rsp(). This patch fixed this issue.
--- drivers/block/aoe/aoecmd.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/block/aoe/aoecmd.c +12 -1
@@ -362,6 +362,7 @@ ata_rw_frameinit(struct frame *f) } ah->cmdstat =ATA_CMD_PIO_READ | writebit | extbit; +dev_hold (t->ifp->nd); skb->dev = t->ifp->nd; }
@@ -402,6 +403,8 @@ aoecmd_ata_rw(struct aoedev *d)__skb_queue_head_init (&queue);__skb_queue_tail (&queue, skb);aoenet_xmit (&queue); + }else { +dev_put (f->t->ifp->nd); }return 1 ; }
@@ -484,10 +487,13 @@ resend(struct aoedev *d, struct frame *fmemcpy (h->dst, t->addr,sizeof h->dst);memcpy (h->src, t->ifp->nd->dev_addr,sizeof h->src); +dev_hold (t->ifp->nd); skb->dev = t->ifp->nd; skb =skb_clone (skb,GFP_ATOMIC ); -if (skb ==NULL ) +if (skb ==NULL ) { +dev_put (t->ifp->nd);return ; + } f->sent =ktime_get ();__skb_queue_head_init (&queue);__skb_queue_tail (&queue, skb);
@@ -618,6 +624,8 @@ probe(struct aoetgt *t)__skb_queue_head_init (&queue);__skb_queue_tail (&queue, skb);aoenet_xmit (&queue); + }else { +dev_put (f->t->ifp->nd); } }
@@ -1396,6 +1404,7 @@ aoecmd_ata_id(struct aoedev *d) ah->cmdstat =ATA_CMD_ID_ATA ; ah->lba3 =0xa0 ; +dev_hold (t->ifp->nd); skb->dev = t->ifp->nd; d->rttavg =RTTAVG_INIT ;
@@ -1405,6 +1414,8 @@ aoecmd_ata_id(struct aoedev *d) skb =skb_clone (skb,GFP_ATOMIC );if (skb) f->sent =ktime_get (); +else +dev_put (t->ifp->nd);return skb; }
Greg Kroah-Hartman
maintainerPATCH 524/691 clk: rockchip: fix error for unknown clocks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Reichel <[email protected]>
commit 12fd64babaca4dc09d072f63eda76ba44119816a upstream.
There is a clk == NULL check after the switch to check for unsupported clk types. Since clk is re-assigned in a loop, this check is useless right now for anything but the first round. Let's fix this up by assigning clk = NULL in the loop before the switch statement.
--- drivers/clk/rockchip/clk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clk/rockchip/clk.c +2 -1
@@ -434,12 +434,13 @@ void rockchip_clk_register_branches(stru struct rockchip_clk_branch *list, unsigned int nr_clk) { -struct clk *clk =NULL ; +struct clk *clk;unsigned int idx;unsigned long flags;for (idx =0 ; idx < nr_clk; idx++, list++) { flags = list->flags; + clk =NULL ;/* catch simple muxes */ switch (list->branch_type) {
Greg Kroah-Hartman
maintainerPATCH 525/691 clk: qcom: dispcc-sm8250: use CLK_SET_RATE_PARENT for branch clocks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
commit 0e93c6320ecde0583de09f3fe801ce8822886fec upstream.
Add CLK_SET_RATE_PARENT for several branch clocks. Such clocks don't have a way to change the rate, so set the parent rate instead.
--- drivers/clk/qcom/dispcc-sm8250.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/qcom/dispcc-sm8250.c +3 -0
@@ -832,6 +832,7 @@ static struct clk_branch disp_cc_mdss_dp &disp_cc_mdss_dp_link1_div_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, },
@@ -867,6 +868,7 @@ static struct clk_branch disp_cc_mdss_dp &disp_cc_mdss_dp_link_div_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, },
@@ -992,6 +994,7 @@ static struct clk_branch disp_cc_mdss_md &disp_cc_mdss_mdp_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, },
Greg Kroah-Hartman
maintainerPATCH 526/691 media: sun4i_csi: Implement link validate for sun4i_csi subdev
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Pinchart <[email protected]>
commit 2dc5d5d401f5c6cecd97800ffef82e8d17d228f0 upstream.
The sun4i_csi driver doesn't implement link validation for the subdev it registers, leaving the link between the subdev and its source unvalidated. Fix it, using the v4l2_subdev_link_validate() helper.
--- drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +5 -0
@@ -40,6 +40,10 @@ static const struct media_entity_operati .link_validate = v4l2_subdev_link_validate, }; +static const struct media_entity_operations sun4i_csi_subdev_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; +static int sun4i_csi_notify_bound (struct v4l2_async_notifier *notifier,struct v4l2_subdev *subdev,struct v4l2_async_subdev *asd)
@@ -218,6 +222,7 @@ static int sun4i_csi_probe(struct platfov4l2_subdev_init (subdev, &sun4i_csi_subdev_ops); subdev->flags =V4L2_SUBDEV_FL_HAS_DEVNODE |V4L2_SUBDEV_FL_HAS_EVENTS ; subdev->entity.function =MEDIA_ENT_F_VID_IF_BRIDGE ; + subdev->entity.ops = &sun4i_csi_subdev_entity_ops; subdev->owner =THIS_MODULE ;snprintf (subdev->name,sizeof (subdev->name),"sun4i-csi-0" );v4l2_set_subdevdata (subdev, csi);
Greg Kroah-Hartman
maintainerPATCH 527/691 media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
commit 599f6899051cb70c4e0aa9fd591b9ee220cb6f14 upstream.
The cec_msg_set_reply_to() helper function never zeroed the struct cec_msg flags field, this can cause unexpected behavior if flags was uninitialized to begin with.
--- include/uapi/linux/cec.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
include/uapi/linux/cec.h +5 -1
@@ -132,6 +132,8 @@ static inline void cec_msg_init(struct c* Set the msg destination to the orig initiator and the msg initiator to the * orig destination. Note that msg and orig may be the same pointer, in which * case the change is done in place. +* +* It also zeroes the reply, timeout and flags fields. */ static inline void cec_msg_set_reply_to (struct cec_msg *msg,struct cec_msg *orig)
@@ -139,7 +141,9 @@ static inline void cec_msg_set_reply_to(/* The destination becomes the initiator and vice versa */ msg->msg[0 ] = (cec_msg_destination (orig) <<4 ) |cec_msg_initiator (orig); - msg->reply = msg->timeout =0 ; + msg->reply =0 ; + msg->timeout =0 ; + msg->flags =0 ; }/* cec_msg flags field */
Greg Kroah-Hartman
maintainerPATCH 528/691 clk: qcom: clk-rpmh: Fix overflow in BCM vote
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Tipton <[email protected]>
commit a4e5af27e6f6a8b0d14bc0d7eb04f4a6c7291586 upstream.
Valid frequencies may result in BCM votes that exceed the max HW value. Set vote ceiling to BCM_TCS_CMD_VOTE_MASK to ensure the votes aren't truncated, which can result in lower frequencies than desired.
--- drivers/clk/qcom/clk-rpmh.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clk/qcom/clk-rpmh.c +2 -0
@@ -270,6 +270,8 @@ static int clk_rpmh_bcm_send_cmd(struct cmd_state =0 ; } + cmd_state =min (cmd_state,BCM_TCS_CMD_VOTE_MASK ); +if (c->last_sent_aggr_state != cmd_state) { cmd.addr = c->res_addr; cmd.data =BCM_TCS_CMD (1 , enable,0 , cmd_state);
Greg Kroah-Hartman
maintainerPATCH 529/691 clk: qcom: gcc-sm8150: De-register gcc_cpuss_ahb_clk_src
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit bab0c7a0bc586e736b7cd2aac8e6391709a70ef2 upstream.
The branch clocks of gcc_cpuss_ahb_clk_src are marked critical and hence these clocks vote on XO blocking the suspend. De-register these clocks and its source as there is no rate setting happening on them.
--- drivers/clk/qcom/gcc-sc8180x.c | 63 ----------------------------------------- 1 file changed, 63 deletions(-)
drivers/clk/qcom/gcc-sc8180x.c +0 -63
@@ -261,28 +261,6 @@ static const struct clk_parent_data gcc_ { .hw = &gpll0_out_even.clkr.hw }, }; -static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { -F (19200000 ,P_BI_TCXO ,1 ,0 ,0 ), -F (50000000 ,P_GPLL0_OUT_MAIN ,12 ,0 ,0 ), -F (100000000 ,P_GPLL0_OUT_MAIN ,6 ,0 ,0 ), - { } -}; - -static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { - .cmd_rcgr =0x48014 , - .mnd_width =0 , - .hid_width =5 , - .parent_map = gcc_parent_map_0, - .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_cpuss_ahb_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, -}; -static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = {F (19200000 ,P_BI_TCXO ,1 ,0 ,0 ),F (50000000 ,P_GPLL0_OUT_EVEN ,6 ,0 ,0 ),
@@ -1600,25 +1578,6 @@ static struct clk_branch gcc_cfg_noc_usb }, }; -/* For CPUSS functionality the AHB clock needs to be left enabled */ -static struct clk_branch gcc_cpuss_ahb_clk = { - .halt_reg =0x48000 , - .halt_check =BRANCH_HALT_VOTED , - .clkr = { - .enable_reg =0x52004 , - .enable_mask =BIT (21 ), - .hw.init = &(struct clk_init_data ){ - .name ="gcc_cpuss_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &gcc_cpuss_ahb_clk_src.clkr.hw - }, - .num_parents =1 , - .flags =CLK_IS_CRITICAL |CLK_SET_RATE_PARENT , - .ops = &clk_branch2_ops, - }, - }, -}; -static struct clk_branch gcc_cpuss_rbcpr_clk = { .halt_reg =0x48008 , .halt_check =BRANCH_HALT ,
@@ -3151,25 +3110,6 @@ static struct clk_branch gcc_sdcc4_apps_ }, }; -/* For CPUSS functionality the SYS NOC clock needs to be left enabled */ -static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { - .halt_reg =0x4819c , - .halt_check =BRANCH_HALT_VOTED , - .clkr = { - .enable_reg =0x52004 , - .enable_mask =BIT (0 ), - .hw.init = &(struct clk_init_data ){ - .name ="gcc_sys_noc_cpuss_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &gcc_cpuss_ahb_clk_src.clkr.hw - }, - .num_parents =1 , - .flags =CLK_IS_CRITICAL |CLK_SET_RATE_PARENT , - .ops = &clk_branch2_ops, - }, - }, -}; -static struct clk_branch gcc_tsif_ahb_clk = { .halt_reg =0x36004 , .halt_check =BRANCH_HALT ,
@@ -4259,8 +4199,6 @@ static struct clk_regmap *gcc_sc8180x_cl [GCC_CFG_NOC_USB3_MP_AXI_CLK] = &gcc_cfg_noc_usb3_mp_axi_clk.clkr, [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr, - [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, - [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
@@ -4397,7 +4335,6 @@ static struct clk_regmap *gcc_sc8180x_cl [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, - [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr, [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr, [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
Greg Kroah-Hartman
maintainerPATCH 530/691 media: venus: fix use after free bug in venus_remove due to race condition
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Wang <[email protected]>
commit c5a85ed88e043474161bbfe54002c89c1cb50ee2 upstream.
in venus_probe, core->work is bound with venus_sys_error_handler, which is used to handle error. The code use core->sys_err_done to make sync work. The core->work is started in venus_event_notify.
If we call venus_remove, there might be an unfished work. The possible sequence is as follows:
CPU0 CPU1
|venus_sys_error_handlervenus_remove |hfi_destroy |venus_hfi_destroy |
kfree(hdev); |
|hfi_reinit
|venus_hfi_queues_reinit
|//use hdevFix it by canceling the work in venus_remove.
--- drivers/media/platform/qcom/venus/core.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/platform/qcom/venus/core.c +1 -0
@@ -409,6 +409,7 @@ static int venus_remove(struct platform_struct device *dev = core->dev;int ret; +cancel_delayed_work_sync (&core->work); ret =pm_runtime_get_sync (dev);WARN_ON (ret <0 );
Greg Kroah-Hartman
maintainerPATCH 531/691 clk: qcom: gcc-sm8250: Do not turn off PCIe GDSCs during gdsc_disable()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
commit ade508b545c969c72cd68479f275a5dd640fd8b9 upstream.
With PWRSTS_OFF_ON, PCIe GDSCs are turned off during gdsc_disable(). This can happen during scenarios such as system suspend and breaks the resume of PCIe controllers from suspend.
So use PWRSTS_RET_ON to indicate the GDSC driver to not turn off the GDSCs during gdsc_disable() and allow the hardware to transition the GDSCs to retention when the parent domain enters low power state during system suspend.
--- drivers/clk/qcom/gcc-sm8250.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/qcom/gcc-sm8250.c +3 -3
@@ -3228,7 +3228,7 @@ static struct gdsc pcie_0_gdsc = { .pd = { .name = "pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc pcie_1_gdsc = {
@@ -3236,7 +3236,7 @@ static struct gdsc pcie_1_gdsc = { .pd = { .name = "pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc pcie_2_gdsc = {
@@ -3244,7 +3244,7 @@ static struct gdsc pcie_2_gdsc = { .pd = { .name = "pcie_2_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc ufs_card_gdsc = {
Greg Kroah-Hartman
maintainerPATCH 532/691 clk: qcom: gcc-sc8180x: Fix the sdcc2 and sdcc4 clocks freq table
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit b8acaf2de8081371761ab4cf1e7a8ee4e7acc139 upstream.
Update the frequency tables of gcc_sdcc2_apps_clk and gcc_sdcc4_apps_clk as per the latest frequency plan.
--- drivers/clk/qcom/gcc-sc8180x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/clk/qcom/gcc-sc8180x.c +2 -3
@@ -895,7 +895,7 @@ static const struct freq_tbl ftbl_gcc_sdF (25000000 ,P_GPLL0_OUT_MAIN ,12 ,1 ,2 ),F (50000000 ,P_GPLL0_OUT_MAIN ,12 ,0 ,0 ),F (100000000 ,P_GPLL0_OUT_MAIN ,6 ,0 ,0 ), - F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(202000000, P_GPLL9_OUT_MAIN, 4, 0, 0), { } };
@@ -918,9 +918,8 @@ static const struct freq_tbl ftbl_gcc_sdF (400000 ,P_BI_TCXO ,12 ,1 ,4 ),F (9600000 ,P_BI_TCXO ,2 ,0 ,0 ),F (19200000 ,P_BI_TCXO ,1 ,0 ,0 ), -F (37500000 ,P_GPLL0_OUT_MAIN ,16 ,0 ,0 ),F (50000000 ,P_GPLL0_OUT_MAIN ,12 ,0 ,0 ), - F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), { } };
Greg Kroah-Hartman
maintainerPATCH 533/691 iio: magnetometer: ak8975: Fix reading for ak099xx sensors
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Barnabás Czémán <[email protected]>
commit 129464e86c7445a858b790ac2d28d35f58256bbe upstream.
Move ST2 reading with overflow handling after measurement data reading.
ST2 register read have to be read after read measurment data, because it means end of the reading and realease the lock on the data. Remove ST2 read skip on interrupt based waiting because ST2 required to be read out at and of the axis read.
--- drivers/iio/magnetometer/ak8975.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
drivers/iio/magnetometer/ak8975.c +16 -16
@@ -661,22 +661,8 @@ static int ak8975_start_read_axis(structif (ret <0 )return ret; -/* This will be executed only for non-interrupt based waiting case */ -if (ret & data->def->ctrl_masks[ST1_DRDY ]) { - ret =i2c_smbus_read_byte_data (client, - data->def->ctrl_regs[ST2 ]); -if (ret <0 ) { -dev_err (&client->dev,"Error in reading ST2\n" ); -return ret; - } -if (ret & (data->def->ctrl_masks[ST2_DERR ] | - data->def->ctrl_masks[ST2_HOFL ])) { -dev_err (&client->dev,"ST2 status error 0x%x\n" , ret); -return -EINVAL ; - } - } - -return 0 ; +/* Return with zero if the data is ready. */ +return !data->def->ctrl_regs[ST1_DRDY ]; }/* Retrieve raw flux value for one of the x, y, or z axis. */
@@ -703,6 +689,20 @@ static int ak8975_read_axis(struct iio_dif (ret <0 ) goto exit; +/* Read out ST2 for release lock on measurment data. */ + ret =i2c_smbus_read_byte_data (client, data->def->ctrl_regs[ST2 ]); +if (ret <0 ) { +dev_err (&client->dev,"Error in reading ST2\n" ); + goto exit; + } + +if (ret & (data->def->ctrl_masks[ST2_DERR ] | + data->def->ctrl_masks[ST2_HOFL ])) { +dev_err (&client->dev,"ST2 status error 0x%x\n" , ret); + ret = -EINVAL ; + goto exit; + } +mutex_unlock (&data->lock);pm_runtime_mark_last_busy (&data->client->dev);
Greg Kroah-Hartman
maintainerPATCH 534/691 tomoyo: fallback to realpath if symlinks pathname does not exist
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <[email protected]>
commit ada1986d07976d60bed5017aa38b7f7cf27883f7 upstream.
Alfred Agrell found that TOMOYO cannot handle execveat(AT_EMPTY_PATH) inside chroot environment where /dev and /proc are not mounted, for commit 51f39a1f0cea ("syscalls: implement execveat() system call") missed that TOMOYO tries to canonicalize argv[0] when the filename fed to the executed program as argv[0] is supplied using potentially nonexistent pathname.
Since "/dev/fd/<fd>" already lost symlink information used for obtaining that <fd>, it is too late to reconstruct symlink's pathname. Although <filename> part of "/dev/fd/<fd>/<filename>" might not be canonicalized, TOMOYO cannot use tomoyo_realpath_nofollow() when /dev or /proc is not mounted. Therefore, fallback to tomoyo_realpath_from_path() when tomoyo_realpath_nofollow() failed.
--- security/tomoyo/domain.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
security/tomoyo/domain.c +6 -3
@@ -723,10 +723,13 @@ int tomoyo_find_next_domain(struct linux ee->r.obj = &ee->obj; ee->obj.path1 = bprm->file->f_path;/* Get symlink's pathname of program. */ - retval = -ENOENT ; exename.name =tomoyo_realpath_nofollow (original_name); -if (!exename.name) - goto out; +if (!exename.name) { +/* Fallback to realpath if symlink's pathname does not exist. */ + exename.name =tomoyo_realpath_from_path (&bprm->file->f_path); +if (!exename.name) + goto out; + }tomoyo_fill_path_info (&exename); retry:/* Check 'aggregator' directive. */
Greg Kroah-Hartman
maintainerPATCH 535/691 net: stmmac: Fix zero-division error when disabling tc cbs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: KhaiWenTan <[email protected]>
commit 675faf5a14c14a2be0b870db30a70764df81e2df upstream.
The commit b8c43360f6e4 ("net: stmmac: No need to calculate speed divider when offload is disabled") allows the "port_transmit_rate_kbps" to be set to a value of 0, which is then passed to the "div_s64" function when tc-cbs is disabled. This leads to a zero-division error.
When tc-cbs is disabled, the idleslope, sendslope, and credit values the credit values are not required to be configured. Therefore, adding a return statement after setting the txQ mode to DCB when tc-cbs is disabled would prevent a zero-division error.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +1 -0
@@ -394,6 +394,7 @@ static int tc_setup_cbs(struct stmmac_prreturn ret; priv->plat->tx_queues_cfg[queue].mode_to_use =MTL_QUEUE_DCB ; +return 0 ; }/* Final adjustments for HW */
Greg Kroah-Hartman
maintainerPATCH 536/691 rtc: at91sam9: fix OF node leak in probe() error path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 73580e2ee6adfb40276bd420da3bb1abae204e10 upstream.
Driver is leaking an OF node reference obtained from of_parse_phandle_with_fixed_args().
--- drivers/rtc/rtc-at91sam9.c | 1 + 1 file changed, 1 insertion(+)
drivers/rtc/rtc-at91sam9.c +1 -0
@@ -368,6 +368,7 @@ static int at91_rtc_probe(struct platforreturn ret; rtc->gpbr =syscon_node_to_regmap (args.np); +of_node_put (args.np); rtc->gpbr_offset = args.args[0 ];if (IS_ERR (rtc->gpbr)) {dev_err (&pdev->dev,"failed to retrieve gpbr regmap, aborting.\n" );
Greg Kroah-Hartman
maintainerPATCH 537/691 Input: adp5589-keys - fix NULL pointer dereference
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit fb5cc65f973661241e4a2b7390b429aa7b330c69 upstream.
We register a devm action to call adp5589_clear_config() and then pass the i2c client as argument so that we can call i2c_get_clientdata() in order to get our device object. However, i2c_set_clientdata() is only being set at the end of the probe function which means that we'll get a NULL pointer dereference in case the probe function fails early.
--- drivers/input/keyboard/adp5589-keys.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/input/keyboard/adp5589-keys.c +3 -6
@@ -936,10 +936,9 @@ static int adp5589_keypad_add(struct adpstatic void adp5589_clear_config (void *data) { -struct i2c_client *client = data; -struct adp5589_kpad *kpad =i2c_get_clientdata (client); +struct adp5589_kpad *kpad = data; -adp5589_write (client, kpad->var->reg (ADP5589_GENERAL_CFG ),0 ); +adp5589_write (kpad->client, kpad->var->reg (ADP5589_GENERAL_CFG ),0 ); } static int adp5589_probe(struct i2c_client *client,
@@ -983,7 +982,7 @@ static int adp5589_probe(struct i2c_clie } error =devm_add_action_or_reset (&client->dev, adp5589_clear_config, - client); + kpad);if (error)return error;
@@ -1010,8 +1009,6 @@ static int adp5589_probe(struct i2c_clieif (error)return error; -i2c_set_clientdata (client, kpad); -dev_info (&client->dev,"Rev.%d keypad, irq %d\n" , revid, client->irq);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 538/691 Input: adp5589-keys - fix adp5589_gpio_get_value()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit c684771630e64bc39bddffeb65dd8a6612a6b249 upstream.
The adp5589 seems to have the same behavior as similar devices as explained in commit 910a9f5636f5 ("Input: adp5588-keys - get value from data out when dir is out").
Basically, when the gpio is set as output we need to get the value from ADP5589_GPO_DATA_OUT_A register instead of ADP5589_GPI_STATUS_A.
--- drivers/input/keyboard/adp5589-keys.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/input/keyboard/adp5589-keys.c +10 -3
@@ -391,10 +391,17 @@ static int adp5589_gpio_get_value(structstruct adp5589_kpad *kpad =gpiochip_get_data (chip);unsigned int bank = kpad->var->bank (kpad->gpiomap[off]);unsigned int bit = kpad->var->bit (kpad->gpiomap[off]); +int val; -return !!(adp5589_read (kpad->client, - kpad->var->reg (ADP5589_GPI_STATUS_A ) + bank) & - bit); +mutex_lock (&kpad->gpio_lock); +if (kpad->dir[bank] & bit) + val = kpad->dat_out[bank]; +else + val =adp5589_read (kpad->client, + kpad->var->reg (ADP5589_GPI_STATUS_A ) + bank); +mutex_unlock (&kpad->gpio_lock); + +return !!(val & bit); } static void adp5589_gpio_set_value(struct gpio_chip *chip,
Greg Kroah-Hartman
maintainerPATCH 539/691 ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[]
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 2f80ce0b78c340e332f04a5801dee5e4ac8cfaeb upstream.
Like other Asus Vivobook models the X1704VAP has its keybopard IRQ (1) described as ActiveLow in the DSDT, which the kernel overrides to EdgeHigh which breaks the keyboard.
Add the X1704VAP to the irq1_level_low_skip_override[] quirk table to fix this.
--- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/acpi/resource.c +7 -0
@@ -443,6 +443,13 @@ static const struct dmi_system_id asus_l }, }, { +/* Asus Vivobook X1704VAP */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), + DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"), + }, + }, + { .ident ="Asus ExpertBook B2402CBA" , .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
Greg Kroah-Hartman
maintainerPATCH 540/691 ACPI: resource: Add Asus ExpertBook B2502CVA to irq1_level_low_skip_override[]
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 056301e7c7c886f96d799edd36f3406cc30e1822 upstream.
Like other Asus ExpertBook models the B2502CVA has its keybopard IRQ (1) described as ActiveLow in the DSDT, which the kernel overrides to EdgeHigh which breaks the keyboard.
Add the B2502CVA to the irq1_level_low_skip_override[] quirk table to fix this.
--- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/acpi/resource.c +7 -0
@@ -517,6 +517,13 @@ static const struct dmi_system_id mainge } }, { +/* Asus ExpertBook B2502CVA */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), + DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"), + }, + }, + {/* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
Greg Kroah-Hartman
maintainerPATCH 541/691 btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit c3b47f49e83197e8dffd023ec568403bcdbb774b upstream.
[BUG]
Syzbot reported a NULL pointer dereference with the following crash:
FAULT_INJECTION: forcing a failure.
start_transaction+0x830/0x1670 fs/btrfs/transaction.c:676 prepare_to_relocate+0x31f/0x4c0 fs/btrfs/relocation.c:3642 relocate_block_group+0x169/0xd20 fs/btrfs/relocation.c:3678 ... BTRFS info (device loop0): balance: ended with status: -12 Oops: general protection fault, probably for non-canonical address 0xdffffc00000000cc: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000660-0x0000000000000667] RIP: 0010:btrfs_update_reloc_root+0x362/0xa80 fs/btrfs/relocation.c:926 Call Trace: <TASK> commit_fs_roots+0x2ee/0x720 fs/btrfs/transaction.c:1496 btrfs_commit_transaction+0xfaf/0x3740 fs/btrfs/transaction.c:2430 del_balance_item fs/btrfs/volumes.c:3678 [inline] reset_balance_state+0x25e/0x3c0 fs/btrfs/volumes.c:3742 btrfs_balance+0xead/0x10c0 fs/btrfs/volumes.c:4574 btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
[CAUSE]
The allocation failure happens at the start_transaction() inside prepare_to_relocate(), and during the error handling we call unset_reloc_control(), which makes fs_info->balance_ctl to be NULL.
Then we continue the error path cleanup in btrfs_balance() by calling reset_balance_state() which will call del_balance_item() to fully delete the balance item in the root tree.
However during the small window between set_reloc_contrl() and unset_reloc_control(), we can have a subvolume tree update and created a reloc_root for that subvolume.
Then we go into the final btrfs_commit_transaction() of del_balance_item(), and into btrfs_update_reloc_root() inside commit_fs_roots().
That function checks if fs_info->reloc_ctl is in the merge_reloc_tree stage, but since fs_info->reloc_ctl is NULL, it results a NULL pointer dereference.
[FIX]
Just add extra check on fs_info->reloc_ctl insidebtrfs_update_reloc_root(), before checkingfs_info->reloc_ctl->merge_reloc_tree.
That DEAD_RELOC_TREE handling is to prevent further modification to the reloc tree during merge stage, but since there is no reloc_ctl at all, we do not need to bother that.
--- fs/btrfs/relocation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/relocation.c +1 -1
@@ -919,7 +919,7 @@ int btrfs_update_reloc_root(struct btrfsbtrfs_grab_root (reloc_root);/* root->reloc_root will stay until current relocation finished */ -if (fs_info->reloc_ctl->merge_reloc_tree && +if (fs_info->reloc_ctl && fs_info->reloc_ctl->merge_reloc_tree &&btrfs_root_refs (root_item) ==0 ) {set_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state);/*
Greg Kroah-Hartman
maintainerPATCH 542/691 btrfs: wait for fixup workers before stopping cleaner kthread during umount
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 41fd1e94066a815a7ab0a7025359e9b40e4b3576 upstream.
During unmount, at close_ctree(), we have the following steps in this order:
1) Park the cleaner kthread - this doesn't destroy the kthread, it basically halts its execution (wake ups against it work but do nothing);
2) We stop the cleaner kthread - this results in freeing the respective struct task_struct;
3) We call btrfs_stop_all_workers() which waits for any jobs running in all the work queues and then free the work queues.
Syzbot reported a case where a fixup worker resulted in a crash when doing a delayed iput on its inode while attempting to wake up the cleaner at btrfs_add_delayed_iput(), because the task_struct of the cleaner kthread was already freed. This can happen during unmount because we don't wait for any fixup workers still running before we call kthread_stop() against the cleaner kthread, which stops and free all its resources.
Fix this by waiting for any fixup workers at close_ctree() before we call kthread_stop() against the cleaner and run pending delayed iputs.
The stack traces reported by syzbot were the following:
BUG: KASAN: slab-use-after-free in __lock_acquire+0x77/0x2050 kernel/locking/lockdep.c:5065
Read of size 8 at addr ffff8880272a8a18 by task kworker/u8:3/52
CPU: 1 UID: 0 PID: 52 Comm: kworker/u8:3 Not tainted 6.12.0-rc1-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
Workqueue: btrfs-fixup btrfs_work_helper
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:377 [inline]
print_report+0x169/0x550 mm/kasan/report.c:488
kasan_report+0x143/0x180 mm/kasan/report.c:601
__lock_acquire+0x77/0x2050 kernel/locking/lockdep.c:5065
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
__raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0xd5/0x120 kernel/locking/spinlock.c:162
class_raw_spinlock_irqsave_constructor include/linux/spinlock.h:551 [inline]
try_to_wake_up+0xb0/0x1480 kernel/sched/core.c:4154
btrfs_writepage_fixup_worker+0xc16/0xdf0 fs/btrfs/inode.c:2842
btrfs_work_helper+0x390/0xc50 fs/btrfs/async-thread.c:314
process_one_work kernel/workqueue.c:3229 [inline]
process_scheduled_works+0xa63/0x1850 kernel/workqueue.c:3310
worker_thread+0x870/0xd30 kernel/workqueue.c:3391
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</TASK>
Allocated by task 2:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
unpoison_slab_object mm/kasan/common.c:319 [inline]
__kasan_slab_alloc+0x66/0x80 mm/kasan/common.c:345
kasan_slab_alloc include/linux/kasan.h:247 [inline]
slab_post_alloc_hook mm/slub.c:4086 [inline]
slab_alloc_node mm/slub.c:4135 [inline]
kmem_cache_alloc_node_noprof+0x16b/0x320 mm/slub.c:4187
alloc_task_struct_node kernel/fork.c:180 [inline]
dup_task_struct+0x57/0x8c0 kernel/fork.c:1107
copy_process+0x5d1/0x3d50 kernel/fork.c:2206
kernel_clone+0x223/0x880 kernel/fork.c:2787
kernel_thread+0x1bc/0x240 kernel/fork.c:2849
create_kthread kernel/kthread.c:412 [inline]
kthreadd+0x60d/0x810 kernel/kthread.c:765
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
Freed by task 61:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x59/0x70 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:230 [inline]
slab_free_hook mm/slub.c:2343 [inline]
slab_free mm/slub.c:4580 [inline]
kmem_cache_free+0x1a2/0x420 mm/slub.c:4682
put_task_struct include/linux/sched/task.h:144 [inline]
delayed_put_task_struct+0x125/0x300 kernel/exit.c:228
rcu_do_batch kernel/rcu/tree.c:2567 [inline]
rcu_core+0xaaa/0x17a0 kernel/rcu/tree.c:2823
handle_softirqs+0x2c5/0x980 kernel/softirq.c:554
__do_softirq kernel/softirq.c:588 [inline]
invoke_softirq kernel/softirq.c:428 [inline]
__irq_exit_rcu+0xf4/0x1c0 kernel/softirq.c:637
irq_exit_rcu+0x9/0x30 kernel/softirq.c:649
instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1037 [inline]
sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1037
asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702
Last potentially related work creation:
kasan_save_stack+0x3f/0x60 mm/kasan/common.c:47
__kasan_record_aux_stack+0xac/0xc0 mm/kasan/generic.c:541
__call_rcu_common kernel/rcu/tree.c:3086 [inline]
call_rcu+0x167/0xa70 kernel/rcu/tree.c:3190
context_switch kernel/sched/core.c:5318 [inline]
__schedule+0x184b/0x4ae0 kernel/sched/core.c:6675
schedule_idle+0x56/0x90 kernel/sched/core.c:6793
do_idle+0x56a/0x5d0 kernel/sched/idle.c:354
cpu_startup_entry+0x42/0x60 kernel/sched/idle.c:424
start_secondary+0x102/0x110 arch/x86/kernel/smpboot.c:314
common_startup_64+0x13e/0x147
The buggy address belongs to the object at ffff8880272a8000
which belongs to the cache task_struct of size 7424
The buggy address is located 2584 bytes inside of
freed 7424-byte region [ffff8880272a8000, ffff8880272a9d00)
The buggy address belongs to the physical page:
page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x272a8
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 00fff00000000040 ffff88801bafa500 dead000000000122 0000000000000000
raw: 0000000000000000 0000000080040004 00000001f5000000 0000000000000000
head: 00fff00000000040 ffff88801bafa500 dead000000000122 0000000000000000
head: 0000000000000000 0000000080040004 00000001f5000000 0000000000000000
head: 00fff00000000003 ffffea00009caa01 ffffffffffffffff 0000000000000000
head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 2, tgid 2 (kthreadd), ts 71247381401, free_ts 71214998153
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x1f3/0x230 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1545 [inline]
get_page_from_freelist+0x3039/0x3180 mm/page_alloc.c:3457
__alloc_pages_noprof+0x256/0x6c0 mm/page_alloc.c:4733
alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265
alloc_slab_page+0x6a/0x120 mm/slub.c:2413
allocate_slab+0x5a/0x2f0 mm/slub.c:2579
new_slab mm/slub.c:2632 [inline]
___slab_alloc+0xcd1/0x14b0 mm/slub.c:3819
__slab_alloc+0x58/0xa0 mm/slub.c:3909
__slab_alloc_node mm/slub.c:3962 [inline]
slab_alloc_node mm/slub.c:4123 [inline]
kmem_cache_alloc_node_noprof+0x1fe/0x320 mm/slub.c:4187
alloc_task_struct_node kernel/fork.c:180 [inline]
dup_task_struct+0x57/0x8c0 kernel/fork.c:1107
copy_process+0x5d1/0x3d50 kernel/fork.c:2206
kernel_clone+0x223/0x880 kernel/fork.c:2787
kernel_thread+0x1bc/0x240 kernel/fork.c:2849
create_kthread kernel/kthread.c:412 [inline]
kthreadd+0x60d/0x810 kernel/kthread.c:765
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
page last free pid 5230 tgid 5230 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
free_pages_prepare mm/page_alloc.c:1108 [inline]
free_unref_page+0xcd0/0xf00 mm/page_alloc.c:2638
discard_slab mm/slub.c:2678 [inline]
__put_partials+0xeb/0x130 mm/slub.c:3146
put_cpu_partial+0x17c/0x250 mm/slub.c:3221
__slab_free+0x2ea/0x3d0 mm/slub.c:4450
qlink_free mm/kasan/quarantine.c:163 [inline]
qlist_free_all+0x9a/0x140 mm/kasan/quarantine.c:179
kasan_quarantine_reduce+0x14f/0x170 mm/kasan/quarantine.c:286
__kasan_slab_alloc+0x23/0x80 mm/kasan/common.c:329
kasan_slab_alloc include/linux/kasan.h:247 [inline]
slab_post_alloc_hook mm/slub.c:4086 [inline]
slab_alloc_node mm/slub.c:4135 [inline]
kmem_cache_alloc_noprof+0x135/0x2a0 mm/slub.c:4142
getname_flags+0xb7/0x540 fs/namei.c:139
do_sys_openat2+0xd2/0x1d0 fs/open.c:1409
do_sys_open fs/open.c:1430 [inline]
__do_sys_openat fs/open.c:1446 [inline]
__se_sys_openat fs/open.c:1441 [inline]
__x64_sys_openat+0x247/0x2a0 fs/open.c:1441
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Memory state around the buggy address:
ffff8880272a8900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880272a8980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff8880272a8a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8880272a8a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880272a8b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================--- fs/btrfs/disk-io.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
fs/btrfs/disk-io.c +11 -0
@@ -4396,6 +4396,17 @@ void __cold close_ctree(struct btrfs_fs_btrfs_cleanup_defrag_inodes (fs_info);/* +* Wait for any fixup workers to complete. +* If we don't wait for them here and they are still running by the time +* we call kthread_stop() against the cleaner kthread further below, we +* get an use-after-free on the cleaner because the fixup worker adds an +* inode to the list of delayed iputs and then attempts to wakeup the +* cleaner kthread, which was already stopped and destroyed. We parked +* already the cleaner, but below we run all pending delayed iputs. +*/ +btrfs_flush_workqueue (fs_info->fixup_workers); + +/* * After we parked the cleaner kthread, ordered extents may have * completed and created new delayed iputs. If one of the async reclaim * tasks is running and in the RUN_DELAYED_IPUTS flush state, then we
Greg Kroah-Hartman
maintainerPATCH 543/691 gpio: davinci: fix lazy disable
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emanuele Ghidoli <[email protected]>
commit 3360d41f4ac490282fddc3ccc0b58679aa5c065d upstream.
On a few platforms such as TI's AM69 device, disable_irq() fails to keep track of the interrupts that happen between disable_irq() and enable_irq() and those interrupts are missed. Use the ->irq_unmask() and ->irq_mask() methods instead of ->irq_enable() and ->irq_disable() to correctly keep track of edges when disable_irq is called.
This solves the issue of disable_irq() not working as expected on such platforms.
--- drivers/gpio/gpio-davinci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpio/gpio-davinci.c +4 -4
@@ -293,7 +293,7 @@ static int davinci_gpio_probe(struct pla* serve as EDMA event triggers. */ -static void gpio_irq_disable (struct irq_data *d) +static void gpio_irq_mask (struct irq_data *d) {struct davinci_gpio_regs __iomem *g =irq2regs (d);uintptr_t mask = (uintptr_t )irq_data_get_irq_handler_data (d);
@@ -302,7 +302,7 @@ static void gpio_irq_disable(struct irq_writel_relaxed (mask, &g->clr_rising); } -static void gpio_irq_enable (struct irq_data *d) +static void gpio_irq_unmask (struct irq_data *d) {struct davinci_gpio_regs __iomem *g =irq2regs (d);uintptr_t mask = (uintptr_t )irq_data_get_irq_handler_data (d);
@@ -328,8 +328,8 @@ static int gpio_irq_type(struct irq_datastatic struct irq_chip gpio_irqchip = { .name ="GPIO" , - .irq_enable = gpio_irq_enable, - .irq_disable = gpio_irq_disable, + .irq_unmask = gpio_irq_unmask, + .irq_mask = gpio_irq_mask, .irq_set_type = gpio_irq_type, .flags =IRQCHIP_SET_TYPE_MASKED |IRQCHIP_SKIP_SET_WAKE , };
Greg Kroah-Hartman
maintainerPATCH 544/691 tracing/hwlat: Fix a race during cpuhp processing
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Li <[email protected]>
commit 2a13ca2e8abb12ee43ada8a107dadca83f140937 upstream.
The cpuhp online/offline processing race also exists in percpu-mode hwlat tracer in theory, apply the fix too. That is:
T1 | T2
[CPUHP_ONLINE] | cpu_device_down()
hwlat_hotplug_workfn() |
| cpus_write_lock()
| takedown_cpu(1)
| cpus_write_unlock()
[CPUHP_OFFLINE] |
cpus_read_lock() |
start_kthread(1) |
cpus_read_unlock() |--- kernel/trace/trace_hwlat.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_hwlat.c +2 -0
@@ -520,6 +520,8 @@ static void hwlat_hotplug_workfn(structif (!hwlat_busy || hwlat_data.thread_mode !=MODE_PER_CPU ) goto out_unlock; +if (!cpu_online (cpu)) + goto out_unlock;if (!cpumask_test_cpu (cpu, tr->tracing_cpumask)) goto out_unlock;
Greg Kroah-Hartman
maintainerPATCH 545/691 tracing/timerlat: Fix a race during cpuhp processing
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Li <[email protected]>
commit 829e0c9f0855f26b3ae830d17b24aec103f7e915 upstream.
There is another found exception that the "timerlat/1" thread was scheduled on CPU0, and lead to timer corruption finally:
``` ODEBUG: init active (active state 0) object: ffff888237c2e108 object type: hrtimer hint: timerlat_irq+0x0/0x220 WARNING: CPU: 0 PID: 426 at lib/debugobjects.c:518 debug_print_object+0x7d/0xb0 Modules linked in: CPU: 0 UID: 0 PID: 426 Comm: timerlat/1 Not tainted 6.11.0-rc7+ #45 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:debug_print_object+0x7d/0xb0 ... Call Trace: <TASK> ? __warn+0x7c/0x110 ? debug_print_object+0x7d/0xb0 ? report_bug+0xf1/0x1d0 ? prb_read_valid+0x17/0x20 ? handle_bug+0x3f/0x70 ? exc_invalid_op+0x13/0x60 ? asm_exc_invalid_op+0x16/0x20 ? debug_print_object+0x7d/0xb0 ? debug_print_object+0x7d/0xb0 ? __pfx_timerlat_irq+0x10/0x10 __debug_object_init+0x110/0x150 hrtimer_init+0x1d/0x60 timerlat_main+0xab/0x2d0 ? __pfx_timerlat_main+0x10/0x10 kthread+0xb7/0xe0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2d/0x40 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> ```
After tracing the scheduling event, it was discovered that the migration of the "timerlat/1" thread was performed during thread creation. Further analysis confirmed that it is because the CPU online processing for osnoise is implemented through workers, which is asynchronous with the offline processing. When the worker was scheduled to create a thread, the CPU may has already been removed from the cpu_online_mask during the offline process, resulting in the inability to select the right CPU:
T1 | T2
[CPUHP_ONLINE] | cpu_device_down()
osnoise_hotplug_workfn() |
| cpus_write_lock()
| takedown_cpu(1)
| cpus_write_unlock()
[CPUHP_OFFLINE] |
cpus_read_lock() |
start_kthread(1) |
cpus_read_unlock() |To fix this, skip online processing if the CPU is already offline.
--- kernel/trace/trace_osnoise.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_osnoise.c +2 -0
@@ -1624,6 +1624,8 @@ static void osnoise_hotplug_workfn(strucmutex_lock (&interface_lock);cpus_read_lock (); +if (!cpu_online (cpu)) + goto out_unlock;if (!cpumask_test_cpu (cpu, &osnoise_cpumask)) goto out_unlock;
Greg Kroah-Hartman
maintainerPATCH 546/691 close_range(): fix the logics in descriptor table trimming
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 678379e1d4f7443b170939525d3312cfc37bf86b upstream.
Cloning a descriptor table picks the size that would cover all currently opened files. That's fine for clone() and unshare(), but for close_range() there's an additional twist - we clone before we close, and it would be a shame to have
close_range(3, ~0U, CLOSE_RANGE_UNSHARE)
leave us with a huge descriptor table when we are not going to keep anything past stderr, just because some large file descriptor used to be open before our call has taken it out.
Unfortunately, it had been dealt with in an inherently racy way - sane_fdtable_size() gets a "don't copy anything past that" argument (passed via unshare_fd() and dup_fd()), close_range() decides how much should be trimmed and passes that to unshare_fd().
The problem is, a range that used to extend to the end of descriptor table back when close_range() had looked at it might very well have stuff grown after it by the time dup_fd() has allocated a new files_struct and started to figure out the capacity of fdtable to be attached to that.
That leads to interesting pathological cases; at the very least it's a QoI issue, since unshare(CLONE_FILES) is atomic in a sense that it takes a snapshot of descriptor table one might have observed at some point. Since CLOSE_RANGE_UNSHARE close_range() is supposed to be a combination of unshare(CLONE_FILES) with plain close_range(), ending up with a weird state that would never occur with unshare(2) is confusing, to put it mildly.
It's not hard to get rid of - all it takes is passing both ends of the range down to sane_fdtable_size(). There we are under ->files_lock, so the race is trivially avoided.
So we do the following:
* switch close_files() from calling unshare_fd() to callingdup_fd().
* undo the calling convention change done to unshare_fd() in60997c3d45d9 "close_range: add CLOSE_RANGE_UNSHARE"
* introduce struct fd_range, pass a pointer to that to dup_fd()
and sane_fdtable_size() instead of "trim everything past that point" they are currently getting. NULL means "we are not going to be punching any holes"; NR_OPEN_MAX is gone.
* make sane_fdtable_size() use find_last_bit() instead of
open-coding it; it's easier to follow that way.
* while we are at it, have dup_fd() report errors by returningERR_PTR(), no need to use a separate int *errorp argument.
--- fs/file.c | 93 +++++++++++++++++------------------------------- include/linux/fdtable.h | 8 ++-- kernel/fork.c | 30 ++++++--------- 3 files changed, 50 insertions(+), 81 deletions(-)
fs/file.c +33 -60
@@ -267,59 +267,45 @@ static inline void __clear_open_fd(unsig__clear_bit (fd /BITS_PER_LONG , fdt->full_fds_bits); } -static unsigned int count_open_files (struct fdtable *fdt) -{ -unsigned int size = fdt->max_fds; -unsigned int i; - -/* Find the last open fd */ -for (i = size /BITS_PER_LONG ; i >0 ; ) { -if (fdt->open_fds[--i]) -break ; - } - i = (i +1 ) *BITS_PER_LONG ; -return i; -} -/* * Note that a sane fdtable size always has to be a multiple of * BITS_PER_LONG, since we have bitmaps that are sized by this. * -* 'max_fds' will normally already be properly aligned, but it -* turns out that in the close_range() -> __close_range() -> -* unshare_fd() -> dup_fd() -> sane_fdtable_size() we can end -* up having a 'max_fds' value that isn't already aligned. -* -* Rather than make close_range() have to worry about this, -* just make that BITS_PER_LONG alignment be part of a sane -* fdtable size. Becuase that's really what it is. +* punch_hole is optional - when close_range() is asked to unshare +* and close, we don't need to copy descriptors in that range, so +* a smaller cloned descriptor table might suffice if the last +* currently opened descriptor falls into that range. */ -static unsigned int sane_fdtable_size (struct fdtable *fdt,unsigned int max_fds) +static unsigned int sane_fdtable_size (struct fdtable *fdt,struct fd_range *punch_hole) { -unsigned int count; +unsigned int last =find_last_bit (fdt->open_fds, fdt->max_fds); - count =count_open_files (fdt); -if (max_fds <NR_OPEN_DEFAULT ) - max_fds =NR_OPEN_DEFAULT ; -return ALIGN (min (count, max_fds),BITS_PER_LONG ); +if (last == fdt->max_fds) +return NR_OPEN_DEFAULT ; +if (punch_hole && punch_hole->to >= last && punch_hole->from <= last) { + last =find_last_bit (fdt->open_fds, punch_hole->from); +if (last == punch_hole->from) +return NR_OPEN_DEFAULT ; + } +return ALIGN (last +1 ,BITS_PER_LONG ); }/* -* Allocate a new files structure and copy contents from the -* passed in files structure. -* errorp will be valid only when the returned files_struct is NULL. +* Allocate a new descriptor table and copy contents from the passed in +* instance. Returns a pointer to cloned table on success, ERR_PTR() +* on failure. For 'punch_hole' see sane_fdtable_size(). */ -struct files_struct *dup_fd (struct files_struct *oldf,unsigned int max_fds,int *errorp) +struct files_struct *dup_fd (struct files_struct *oldf,struct fd_range *punch_hole) {struct files_struct *newf;struct file **old_fds, **new_fds;unsigned int open_files, i;struct fdtable *old_fdt, *new_fdt; +int error; - *errorp = -ENOMEM ; newf =kmem_cache_alloc (files_cachep,GFP_KERNEL );if (!newf) - goto out; +return ERR_PTR (-ENOMEM );atomic_set (&newf->count,1 );
@@ -336,7 +322,7 @@ struct files_struct *dup_fd(struct filesspin_lock (&oldf->file_lock); old_fdt =files_fdtable (oldf); - open_files =sane_fdtable_size (old_fdt, max_fds); + open_files =sane_fdtable_size (old_fdt, punch_hole);/* * Check whether we need to allocate a larger fd array and fd set.
@@ -349,14 +335,14 @@ struct files_struct *dup_fd(struct files new_fdt =alloc_fdtable (open_files -1 );if (!new_fdt) { - *errorp = -ENOMEM ; + error = -ENOMEM ; goto out_release; }/* beyond sysctl_nr_open; nothing to do */ if (unlikely (new_fdt->max_fds < open_files)) {__free_fdtable (new_fdt); - *errorp = -EMFILE ; + error = -EMFILE ; goto out_release; }
@@ -367,7 +353,7 @@ struct files_struct *dup_fd(struct files*/ spin_lock (&oldf->file_lock); old_fdt =files_fdtable (oldf); - open_files =sane_fdtable_size (old_fdt, max_fds); + open_files =sane_fdtable_size (old_fdt, punch_hole); }copy_fd_bitmaps (new_fdt, old_fdt, open_files /BITS_PER_LONG );
@@ -401,8 +387,7 @@ struct files_struct *dup_fd(struct files out_release:kmem_cache_free (files_cachep, newf); -out: -return NULL ; +return ERR_PTR (error); }static struct fdtable *close_files (struct files_struct * files)
@@ -736,37 +721,25 @@ int __close_range(unsigned fd, unsignedif (fd > max_fd)return -EINVAL ; -if (flags &CLOSE_RANGE_UNSHARE ) { -int ret; -unsigned int max_unshare_fds =NR_OPEN_MAX ; +if ((flags &CLOSE_RANGE_UNSHARE ) &&atomic_read (&cur_fds->count) >1 ) { +struct fd_range range = {fd, max_fd}, *punch_hole = ⦥/* * If the caller requested all fds to be made cloexec we always * copy all of the file descriptors since they still want to * use them. */ -if (!(flags &CLOSE_RANGE_CLOEXEC )) { -/* -* If the requested range is greater than the current -* maximum, we're closing everything so only copy all -* file descriptors beneath the lowest file descriptor. -*/ -rcu_read_lock (); -if (max_fd >=last_fd (files_fdtable (cur_fds))) - max_unshare_fds = fd; -rcu_read_unlock (); - } - - ret =unshare_fd (CLONE_FILES , max_unshare_fds, &fds); -if (ret) -return ret; +if (flags &CLOSE_RANGE_CLOEXEC ) + punch_hole =NULL ; + fds =dup_fd (cur_fds, punch_hole); +if (IS_ERR (fds)) +return PTR_ERR (fds);/* * We used to share our file descriptor table, and have now * created a private one, make sure we're using it below. */ -if (fds) -swap (cur_fds, fds); +swap (cur_fds, fds); }if (flags &CLOSE_RANGE_CLOEXEC )
include/linux/fdtable.h +4 -4
@@ -22,7 +22,6 @@* as this is the granularity returned by copy_fdset(). */ #define NR_OPEN_DEFAULT BITS_PER_LONG -#define NR_OPEN_MAX ~0Ustruct fdtable {unsigned int max_fds;
@@ -117,7 +116,10 @@ struct task_struct;void put_files_struct (struct files_struct *fs);int unshare_files (void ); -struct files_struct *dup_fd (struct files_struct *,unsigned ,int *) __latent_entropy; +struct fd_range { +unsigned int from, to; +}; +struct files_struct *dup_fd (struct files_struct *,struct fd_range *) __latent_entropy;void do_close_on_exec (struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned),
@@ -126,8 +128,6 @@ int iterate_fd(struct files_struct *, unextern int close_fd (unsigned int fd);extern int __close_range (unsigned int fd,unsigned int max_fd,unsigned int flags);extern int close_fd_get_file (unsigned int fd,struct file **res); -extern int unshare_fd (unsigned long unshare_flags,unsigned int max_fds, -struct files_struct **new_fdp);extern struct kmem_cache *files_cachep;
kernel/fork.c +13 -17
@@ -1547,28 +1547,25 @@ static int copy_fs(unsigned long clone_fstatic int copy_files (unsigned long clone_flags,struct task_struct *tsk) {struct files_struct *oldf, *newf; -int error =0 ;/* * A background process may not have any files ... */ oldf = current->files;if (!oldf) - goto out; +return 0 ;if (clone_flags &CLONE_FILES ) {atomic_inc (&oldf->count); - goto out; +return 0 ; } - newf =dup_fd (oldf,NR_OPEN_MAX , &error); -if (!newf) - goto out; + newf =dup_fd (oldf,NULL ); +if (IS_ERR (newf)) +return PTR_ERR (newf); tsk->files = newf; - error =0 ; -out: -return error; +return 0 ; }static int copy_io (unsigned long clone_flags,struct task_struct *tsk)
@@ -3024,17 +3021,16 @@ static int unshare_fs(unsigned long unsh/* * Unshare file descriptor table if it is being shared */ -int unshare_fd (unsigned long unshare_flags,unsigned int max_fds, -struct files_struct **new_fdp) +static int unshare_fd (unsigned long unshare_flags,struct files_struct **new_fdp) {struct files_struct *fd = current->files; -int error =0 ;if ((unshare_flags &CLONE_FILES ) && (fd &&atomic_read (&fd->count) >1 )) { - *new_fdp =dup_fd (fd, max_fds, &error); -if (!*new_fdp) -return error; + fd =dup_fd (fd,NULL ); +if (IS_ERR (fd)) +return PTR_ERR (fd); + *new_fdp = fd; }return 0 ;
@@ -3092,7 +3088,7 @@ int ksys_unshare(unsigned long unshare_f err =unshare_fs (unshare_flags, &new_fs);if (err) goto bad_unshare_out; - err =unshare_fd (unshare_flags,NR_OPEN_MAX , &new_fd); + err =unshare_fd (unshare_flags, &new_fd);if (err) goto bad_unshare_cleanup_fs; err =unshare_userns (unshare_flags, &new_cred);
@@ -3187,7 +3183,7 @@ int unshare_files(void)struct files_struct *old, *copy =NULL ;int error; - error =unshare_fd (CLONE_FILES ,NR_OPEN_MAX , ©); + error =unshare_fd (CLONE_FILES , ©);if (error || !copy)return error;
Greg Kroah-Hartman
maintainerPATCH 547/691 drm/sched: Add locking to drm_sched_entity_modify_sched
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <[email protected]>
commit 4286cc2c953983d44d248c9de1c81d3a9643345c upstream.
Without the locking amdgpu currently can race between amdgpu_ctx_set_entity_priority() (via drm_sched_entity_modify_sched()) and drm_sched_job_arm(), leading to the latter accesing potentially inconsitent entity->sched_list and entity->num_sched_list pair.
v2:
* Improve commit message. (Philipp)
--- drivers/gpu/drm/scheduler/sched_entity.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/scheduler/sched_entity.c +2 -0
@@ -99,8 +99,10 @@ void drm_sched_entity_modify_sched(struc {WARN_ON (!num_sched_list || !sched_list); +spin_lock (&entity->rq_lock); entity->sched_list = sched_list; entity->num_sched_list = num_sched_list; +spin_unlock (&entity->rq_lock); }EXPORT_SYMBOL (drm_sched_entity_modify_sched);
Greg Kroah-Hartman
maintainerPATCH 548/691 drm/amd/display: Fix system hang while resume with TBT monitor
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Chung <[email protected]>
commit 52d4e3fb3d340447dcdac0e14ff21a764f326907 upstream.
[Why]
Connected with a Thunderbolt monitor and do the suspend and the system may hang while resume.
The TBT monitor HPD will be triggered during the resume procedure and call the drm_client_modeset_probe() while
struct drm_connector connector->dev->master is NULL.
It will mess up the pipe topology after resume.
[How]
Skip the TBT monitor HPD during the resume procedure because we currently will probe the connectors after resume by default.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +6 -0
@@ -697,6 +697,12 @@ void dmub_hpd_callback(struct amdgpu_devreturn ; } +/* Skip DMUB HPD IRQ in suspend/resume. We will probe them later. */ +if (notify->type ==DMUB_NOTIFICATION_HPD && adev->in_suspend) { +DRM_INFO ("Skip DMUB HPD IRQ callback in suspend/resume\n" ); +return ; + } + link_index = notify->link_index; link = adev->dm.dc->links[link_index]; dev = adev->dm.ddev;
Greg Kroah-Hartman
maintainerPATCH 549/691 kconfig: qconf: fix buffer overflow in debug links
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 984ed20ece1c6c20789ece040cbff3eb1a388fa9 ]
If you enable "Option -> Show Debug Info" and click a link, the program terminates with the following error:
*** buffer overflow detected ***: terminated
The buffer overflow is caused by the following line:
strcat(data, "$");
The buffer needs one more byte to accommodate the additional character.
--- scripts/kconfig/qconf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/kconfig/qconf.cc +1 -1
@@ -1172,7 +1172,7 @@ void ConfigInfoView::clicked(const QUrl &url) { QByteArray str = url.toEncoded(); const std::size_t count = str.size(); - char *data = new char[count + 1]; + char *data = new char[count + 2]; // '$' + '\0' struct symbol **result; struct menu *m = NULL;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 550/691 device property: Add fwnode_iomap()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anand Ashok Dumbre <[email protected]>
[ Upstream commit eca6e2d4a4a4b824f055eeaaa24f1c2327fb91a2 ]
This patch introduces a new helper routine - fwnode_iomap(), which allows to map the memory mapped IO for a given device node.
This implementation does not cover the ACPI case and may be expanded in the future. The main purpose here is to be able to develop resource provider agnostic drivers.
Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
--- drivers/base/property.c | 16 ++++++++++++++++ include/linux/property.h | 2 ++ 2 files changed, 18 insertions(+)
drivers/base/property.c +16 -0
@@ -1050,6 +1050,22 @@ int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index) }EXPORT_SYMBOL (fwnode_irq_get); +/** +* fwnode_iomap - Maps the memory mapped IO for a given fwnode +* @fwnode: Pointer to the firmware node +* @index: Index of the IO range +* +* Returns a pointer to the mapped memory. +*/ +void __iomem *fwnode_iomap (struct fwnode_handle *fwnode,int index) +{ +if (IS_ENABLED (CONFIG_OF_ADDRESS ) &&is_of_node (fwnode)) +return of_iomap (to_of_node (fwnode), index); + +return NULL ; +} +EXPORT_SYMBOL (fwnode_iomap); +/** * fwnode_graph_get_next_endpoint - Get next endpoint firmware node * @fwnode: Pointer to the parent firmware node
include/linux/property.h +2 -0
@@ -126,6 +126,8 @@ void fwnode_handle_put(struct fwnode_handle *fwnode);int fwnode_irq_get (const struct fwnode_handle *fwnode,unsigned int index); +void __iomem *fwnode_iomap (struct fwnode_handle *fwnode,int index); +unsigned int device_get_child_node_count (struct device *dev); static inline bool device_property_read_bool(struct device *dev,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 551/691 device property: Add fwnode_irq_get_byname
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil R <[email protected]>
[ Upstream commit ca0acb511c21738b32386ce0f85c284b351d919e ]
Add fwnode_irq_get_byname() to get an interrupt by name from either ACPI table or Device Tree, whichever is used for enumeration.
In the ACPI case, this allow us to use 'interrupt-names' in _DSD which can be mapped to Interrupt() resource by index. The implementation is similar to 'interrupt-names' in the Device Tree.
Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
--- drivers/base/property.c | 29 +++++++++++++++++++++++++++++ include/linux/property.h | 1 + 2 files changed, 30 insertions(+)
drivers/base/property.c +29 -0
@@ -1066,6 +1066,35 @@ void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index) }EXPORT_SYMBOL (fwnode_iomap); +/** +* fwnode_irq_get_byname - Get IRQ from a fwnode using its name +* @fwnode: Pointer to the firmware node +* @name: IRQ name +* +* Description: +* Find a match to the string @name in the 'interrupt-names' string array +* in _DSD for ACPI, or of_node for Device Tree. Then get the Linux IRQ +* number of the IRQ resource corresponding to the index of the matched +* string. +* +* Return: +* Linux IRQ number on success, or negative errno otherwise. +*/ +int fwnode_irq_get_byname (const struct fwnode_handle *fwnode,const char *name) +{ +int index; + +if (!name) +return -EINVAL ; + + index =fwnode_property_match_string (fwnode,"interrupt-names" , name); +if (index <0 ) +return index; + +return fwnode_irq_get (fwnode, index); +} +EXPORT_SYMBOL (fwnode_irq_get_byname); +/** * fwnode_graph_get_next_endpoint - Get next endpoint firmware node * @fwnode: Pointer to the parent firmware node
include/linux/property.h +1 -0
@@ -125,6 +125,7 @@ struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode);void fwnode_handle_put (struct fwnode_handle *fwnode);int fwnode_irq_get (const struct fwnode_handle *fwnode,unsigned int index); +int fwnode_irq_get_byname (const struct fwnode_handle *fwnode,const char *name);void __iomem *fwnode_iomap (struct fwnode_handle *fwnode,int index);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 552/691 i2c: smbus: Use device_*() functions instead of of_*()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil R <[email protected]>
[ Upstream commit a263a84088f689bf0c1552a510b25d0bcc45fcae ]
Change of_*() functions to device_*() for firmware agnostic usage. This allows to have the smbus_alert interrupt without any changes in the controller drivers using the ACPI table.
Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
--- drivers/i2c/i2c-core-base.c | 2 +- drivers/i2c/i2c-core-smbus.c | 11 ++++++----- drivers/i2c/i2c-smbus.c | 5 +++-- include/linux/i2c-smbus.h | 6 +++--- 4 files changed, 13 insertions(+), 11 deletions(-)
drivers/i2c/i2c-core-base.c +1 -1
@@ -1526,7 +1526,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } - res =of_i2c_setup_smbus_alert (adap); + res =i2c_setup_smbus_alert (adap);if (res) goto out_reg;
drivers/i2c/i2c-core-smbus.c +6 -5
@@ -14,6 +14,7 @@#include <linux/err.h> #include <linux/i2c.h> #include <linux/i2c-smbus.h> +#include <linux/property.h> #include <linux/slab.h> #include "i2c-core.h"
@@ -701,13 +702,13 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter, }EXPORT_SYMBOL_GPL (i2c_new_smbus_alert_device); -#if IS_ENABLED (CONFIG_I2C_SMBUS ) &&IS_ENABLED (CONFIG_OF ) -int of_i2c_setup_smbus_alert (struct i2c_adapter *adapter) +#if IS_ENABLED (CONFIG_I2C_SMBUS ) +int i2c_setup_smbus_alert (struct i2c_adapter *adapter) {int irq; - irq =of_property_match_string (adapter->dev.of_node,"interrupt-names" , -"smbus_alert" ); + irq =device_property_match_string (adapter->dev.parent,"interrupt-names" , +"smbus_alert" );if (irq == -EINVAL || irq == -ENODATA )return 0 ;else if (irq <0 )
@@ -715,5 +716,5 @@ int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter) return PTR_ERR_OR_ZERO(i2c_new_smbus_alert_device(adapter, NULL)); } -EXPORT_SYMBOL_GPL (of_i2c_setup_smbus_alert); +EXPORT_SYMBOL_GPL (i2c_setup_smbus_alert);#endif
drivers/i2c/i2c-smbus.c +3 -2
@@ -13,7 +13,7 @@#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_irq.h> +#include <linux/property.h> #include <linux/slab.h> #include <linux/workqueue.h>
@@ -178,7 +178,8 @@ static int smbalert_probe(struct i2c_client *ara,if (setup) { irq = setup->irq; }else { - irq =of_irq_get_byname (adapter->dev.of_node,"smbus_alert" ); + irq =fwnode_irq_get_byname (dev_fwnode (adapter->dev.parent), +"smbus_alert" );if (irq <=0 )return irq; }
include/linux/i2c-smbus.h +3 -3
@@ -30,10 +30,10 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter, struct i2c_smbus_alert_setup *setup);int i2c_handle_smbus_alert (struct i2c_client *ara); -#if IS_ENABLED (CONFIG_I2C_SMBUS ) &&IS_ENABLED (CONFIG_OF ) -int of_i2c_setup_smbus_alert (struct i2c_adapter *adap); +#if IS_ENABLED (CONFIG_I2C_SMBUS ) +int i2c_setup_smbus_alert (struct i2c_adapter *adap);#else -static inline int of_i2c_setup_smbus_alert (struct i2c_adapter *adap) +static inline int i2c_setup_smbus_alert (struct i2c_adapter *adap) {return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 553/691 i2c: create debugfs entry per adapter
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit 73febd775bdbdb98c81255ff85773ac410ded5c4 ]
Two drivers already implement custom debugfs handling for their i2c_adapter and more will come. So, let the core create a debugfs directory per adapter and pass that to drivers for their debugfs files.
Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
--- drivers/i2c/i2c-core-base.c | 11 +++++++++++ include/linux/i2c.h | 2 ++ 2 files changed, 13 insertions(+)
drivers/i2c/i2c-core-base.c +11 -0
@@ -16,6 +16,7 @@#include <linux/acpi.h> #include <linux/clk/clk-conf.h> #include <linux/completion.h> +#include <linux/debugfs.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/errno.h>
@@ -66,6 +67,8 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);static DEFINE_STATIC_KEY_FALSE (i2c_trace_msg_key);static bool is_registered; +static struct dentry *i2c_debugfs_root; +int i2c_transfer_trace_reg (void ) {static_branch_inc (&i2c_trace_msg_key);
@@ -1526,6 +1529,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } + adap->debugfs =debugfs_create_dir (dev_name (&adap->dev), i2c_debugfs_root); + res =i2c_setup_smbus_alert (adap);if (res) goto out_reg;
@@ -1564,6 +1569,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)return 0 ; out_reg: +debugfs_remove_recursive (adap->debugfs);init_completion (&adap->dev_released);device_unregister (&adap->dev);wait_for_completion (&adap->dev_released);
@@ -1765,6 +1771,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)i2c_host_notify_irq_teardown (adap); +debugfs_remove_recursive (adap->debugfs); +/* wait until all references to the device are gone * * FIXME: This is old code and should ideally be replaced by an
@@ -2062,6 +2070,8 @@ static int __init i2c_init(void) is_registered = true; + i2c_debugfs_root =debugfs_create_dir ("i2c" ,NULL ); +#ifdef CONFIG_I2C_COMPAT i2c_adapter_compat_class =class_compat_register ("i2c-adapter" );if (!i2c_adapter_compat_class) {
@@ -2100,6 +2110,7 @@ static void __exit i2c_exit(void)#ifdef CONFIG_I2C_COMPAT class_compat_unregister (i2c_adapter_compat_class);#endif +debugfs_remove_recursive (i2c_debugfs_root);bus_unregister (&i2c_bus_type);tracepoint_synchronize_unregister (); }
include/linux/i2c.h +2 -0
@@ -740,6 +740,8 @@ struct i2c_adapter {struct irq_domain *host_notify_domain;struct regulator *bus_regulator; + +struct dentry *debugfs; };#define to_i2c_adapter (d) container_of(d, struct i2c_adapter, dev)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 554/691 i2c: core: Lock address during client device instantiation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit <[email protected]>
[ Upstream commit 8d3cefaf659265aa82b0373a563fdb9d16a2b947 ]
Krzysztof reported an issue [0] which is caused by parallel attempts to instantiate the same I2C client device. This can happen if driver supports auto-detection, but certain devices are also instantiated explicitly.
The original change isn't actually wrong, it just revealed that I2C core isn't prepared yet to handle this scenario.
Calls to i2c_new_client_device() can be nested, therefore we can't use a simple mutex here. Parallel instantiation of devices at different addresses is ok, so we just have to prevent parallel instantiation at the same address. We can use a bitmap with one bit per 7-bit I2C client address, and atomic bit operations to set/check/clear bits.
Now a parallel attempt to instantiate a device at the same address will result in -EBUSY being returned, avoiding the "sysfs: cannot create duplicate filename" splash.
Note: This patch version includes small cosmetic changes to the Tested-by
version, only functional change is that address locking is supported for slave addresses too.
[0] https://lore.kernel.org/linux-i2c/[email protected]/T/#m12706546e8e2414d8f1a0dc61c53393f731685cc
--- drivers/i2c/i2c-core-base.c | 28 ++++++++++++++++++++++++++++ include/linux/i2c.h | 3 +++ 2 files changed, 31 insertions(+)
drivers/i2c/i2c-core-base.c +28 -0
@@ -917,6 +917,27 @@ int i2c_dev_irq_from_resources(const struct resource *resources,return 0 ; } +/* +* Serialize device instantiation in case it can be instantiated explicitly +* and by auto-detection +*/ +static int i2c_lock_addr (struct i2c_adapter *adap,unsigned short addr, +unsigned short flags) +{ +if (!(flags &I2C_CLIENT_TEN ) && +test_and_set_bit (addr, adap->addrs_in_instantiation)) +return -EBUSY ; + +return 0 ; +} + +static void i2c_unlock_addr (struct i2c_adapter *adap,unsigned short addr, +unsigned short flags) +{ +if (!(flags &I2C_CLIENT_TEN )) +clear_bit (addr, adap->addrs_in_instantiation); +} +/** * i2c_new_client_device - instantiate an i2c device * @adap: the adapter managing the device
@@ -963,6 +984,10 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf goto out_err_silent; } + status =i2c_lock_addr (adap, client->addr, client->flags); +if (status) + goto out_err_silent; +/* Check for address business */ status =i2c_check_addr_busy (adap,i2c_encode_flags_to_addr (client));if (status)
@@ -993,6 +1018,8 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *infdev_dbg (&adap->dev,"client [%s] registered with bus id %s\n" , client->name,dev_name (&client->dev)); +i2c_unlock_addr (adap, client->addr, client->flags); +return client; out_remove_swnode:
@@ -1003,6 +1030,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *infdev_err (&adap->dev,"Failed to register i2c client %s at 0x%02x (%d)\n" , client->name, client->addr, status); +i2c_unlock_addr (adap, client->addr, client->flags); out_err_silent:kfree (client);return ERR_PTR (status);
include/linux/i2c.h +3 -0
@@ -742,6 +742,9 @@ struct i2c_adapter {struct regulator *bus_regulator;struct dentry *debugfs; + +/* 7bit address space */ +DECLARE_BITMAP (addrs_in_instantiation,1 <<7 ); };#define to_i2c_adapter (d) container_of(d, struct i2c_adapter, dev)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 555/691 i2c: xiic: Use devm_clk_get_enabled()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andi Shyti <[email protected]>
[ Upstream commit 8390dc7477e49e4acc9e553f385f4ff59d186efe ]
Replace the pair of functions, devm_clk_get() and clk_prepare_enable(), with a single function devm_clk_get_enabled().
Stable-dep-of: 0c8d604dea43 ("i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled")
--- drivers/i2c/busses/i2c-xiic.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-)
drivers/i2c/busses/i2c-xiic.c +7 -13
@@ -837,16 +837,11 @@ static int xiic_i2c_probe(struct platform_device *pdev)mutex_init (&i2c->lock); - i2c->clk =devm_clk_get (&pdev->dev,NULL ); + i2c->clk =devm_clk_get_enabled (&pdev->dev,NULL );if (IS_ERR (i2c->clk))return dev_err_probe (&pdev->dev,PTR_ERR (i2c->clk), -"input clock not found.\n" ); +"failed to enable input clock.\n" ); - ret =clk_prepare_enable (i2c->clk); -if (ret) { -dev_err (&pdev->dev,"Unable to enable clock.\n" ); -return ret; - } i2c->dev = &pdev->dev;pm_runtime_set_autosuspend_delay (i2c->dev,XIIC_PM_TIMEOUT );pm_runtime_use_autosuspend (i2c->dev);
@@ -858,7 +853,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)if (ret <0 ) {dev_err (&pdev->dev,"Cannot claim IRQ\n" ); - goto err_clk_dis; + goto err_pm_disable; } i2c->singlemaster =
@@ -879,14 +874,14 @@ static int xiic_i2c_probe(struct platform_device *pdev) ret =xiic_reinit (i2c);if (ret <0 ) {dev_err (&pdev->dev,"Cannot xiic_reinit\n" ); - goto err_clk_dis; + goto err_pm_disable; }/* add i2c adapter to i2c tree */ ret =i2c_add_adapter (&i2c->adap);if (ret) {xiic_deinit (i2c); - goto err_clk_dis; + goto err_pm_disable; }if (pdata) {
@@ -897,10 +892,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)return 0 ; -err_clk_dis: +err_pm_disable:pm_runtime_set_suspended (&pdev->dev);pm_runtime_disable (&pdev->dev); -clk_disable_unprepare (i2c->clk); +return ret; }
@@ -918,7 +913,6 @@ static int xiic_i2c_remove(struct platform_device *pdev)xiic_deinit (i2c);pm_runtime_put_sync (i2c->dev); -clk_disable_unprepare (i2c->clk);pm_runtime_disable (&pdev->dev);pm_runtime_set_suspended (&pdev->dev);pm_runtime_dont_use_autosuspend (&pdev->dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 556/691 i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 0c8d604dea437b69a861479b413d629bc9b3da70 ]
It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it.
--- drivers/i2c/busses/i2c-xiic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-xiic.c +1 -1
@@ -893,8 +893,8 @@ static int xiic_i2c_probe(struct platform_device *pdev)return 0 ; err_pm_disable: -pm_runtime_set_suspended (&pdev->dev);pm_runtime_disable (&pdev->dev); +pm_runtime_set_suspended (&pdev->dev);return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 557/691 spi: bcm63xx: Fix missing pm_runtime_disable()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 265697288ec2160ca84707565d6641d46f69b0ff ]
The pm_runtime_disable() is missing in the remove function, fix it by using devm_pm_runtime_enable(), so the pm_runtime_disable() in the probe error path can also be removed.
--- drivers/spi/spi-bcm63xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/spi/spi-bcm63xx.c +4 -4
@@ -595,13 +595,15 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)bcm_spi_writeb (bs,SPI_INTR_CLEAR_ALL ,SPI_INT_STATUS ); -pm_runtime_enable (&pdev->dev); + ret =devm_pm_runtime_enable (&pdev->dev); +if (ret) + goto out_clk_disable;/* register and we are done */ ret =devm_spi_register_master (dev, master);if (ret) {dev_err (dev,"spi register failed\n" ); - goto out_pm_disable; + goto out_clk_disable; } dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
@@ -609,8 +611,6 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)return 0 ; -out_pm_disable: -pm_runtime_disable (&pdev->dev); out_clk_disable:clk_disable_unprepare (clk); out_err:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 558/691 ext4: properly sync file size update after O_SYNC direct IO
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
[ Upstream commit 91562895f8030cb9a0470b1db49de79346a69f91 ]
Gao Xiang has reported that on ext4 O_SYNC direct IO does not properly sync file size update and thus if we crash at unfortunate moment, the file can have smaller size although O_SYNC IO has reported successful completion. The problem happens because update of on-disk inode size is handled in ext4_dio_write_iter() *after* iomap_dio_rw() (and thus dio_complete() in particular) has returned and generic_file_sync() gets called by dio_complete(). Fix the problem by handling on-disk inode size update directly in our ->end_io completion handler.
References: https://lore.kernel.org/all/[email protected]
Stable-dep-of: dda898d7ffe8 ("ext4: dax: fix overflowing extents beyond inode size when partially writing")
--- fs/ext4/file.c | 153 +++++++++++++++++++++---------------------------- 1 file changed, 65 insertions(+), 88 deletions(-)
fs/ext4/file.c +65 -88
@@ -279,80 +279,38 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb, }static ssize_t ext4_handle_inode_extension (struct inode *inode,loff_t offset, -ssize_t written,size_t count) +ssize_t count) {handle_t *handle; -bool truncate = false; -u8 blkbits = inode->i_blkbits; -ext4_lblk_t written_blk, end_blk; -int ret; - -/* -* Note that EXT4_I(inode)->i_disksize can get extended up to -* inode->i_size while the I/O was running due to writeback of delalloc -* blocks. But, the code in ext4_iomap_alloc() is careful to use -* zeroed/unwritten extents if this is possible; thus we won't leave -* uninitialized blocks in a file even if we didn't succeed in writing -* as much as we intended. -*/ -WARN_ON_ONCE (i_size_read (inode) <EXT4_I (inode)->i_disksize); -if (offset + count <=EXT4_I (inode)->i_disksize) { -/* -* We need to ensure that the inode is removed from the orphan -* list if it has been added prematurely, due to writeback of -* delalloc blocks. -*/ -if (!list_empty (&EXT4_I (inode)->i_orphan) && inode->i_nlink) { - handle =ext4_journal_start (inode,EXT4_HT_INODE ,2 ); - -if (IS_ERR (handle)) { -ext4_orphan_del (NULL , inode); -return PTR_ERR (handle); - } - -ext4_orphan_del (handle, inode); -ext4_journal_stop (handle); - } - -return written; - } - -if (written <0 ) - goto truncate; +lockdep_assert_held_write (&inode->i_rwsem); handle =ext4_journal_start (inode,EXT4_HT_INODE ,2 ); -if (IS_ERR (handle)) { - written =PTR_ERR (handle); - goto truncate; - } +if (IS_ERR (handle)) +return PTR_ERR (handle); -if (ext4_update_inode_size (inode, offset + written)) { - ret =ext4_mark_inode_dirty (handle, inode); +if (ext4_update_inode_size (inode, offset + count)) { +int ret =ext4_mark_inode_dirty (handle, inode);if (unlikely (ret)) { - written = ret;ext4_journal_stop (handle); - goto truncate; +return ret; } } -/* -* We may need to truncate allocated but not written blocks beyond EOF. -*/ - written_blk =ALIGN (offset + written,1 << blkbits); - end_blk =ALIGN (offset + count,1 << blkbits); -if (written_blk < end_blk &&ext4_can_truncate (inode)) - truncate = true; - -/* -* Remove the inode from the orphan list if it has been extended and -* everything went OK. -*/ -if (!truncate && inode->i_nlink) +if (inode->i_nlink)ext4_orphan_del (handle, inode);ext4_journal_stop (handle); -if (truncate) { -truncate: +return count; +} + +/* +* Clean up the inode after DIO or DAX extending write has completed and the +* inode size has been updated using ext4_handle_inode_extension(). +*/ +static void ext4_inode_extension_cleanup (struct inode *inode,ssize_t count) +{ +lockdep_assert_held_write (&inode->i_rwsem); +if (count <0 ) {ext4_truncate_failed_write (inode);/* * If the truncate operation failed early, then the inode may
@@ -361,9 +319,28 @@ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,*/ if (inode->i_nlink)ext4_orphan_del (NULL , inode); +return ; } +/* +* If i_disksize got extended due to writeback of delalloc blocks while +* the DIO was running we could fail to cleanup the orphan list in +* ext4_handle_inode_extension(). Do it now. +*/ +if (!list_empty (&EXT4_I (inode)->i_orphan) && inode->i_nlink) { +handle_t *handle =ext4_journal_start (inode,EXT4_HT_INODE ,2 ); -return written; +if (IS_ERR (handle)) { +/* +* The write has successfully completed. Not much to +* do with the error here so just cleanup the orphan +* list and hope for the best. +*/ +ext4_orphan_del (NULL , inode); +return ; + } +ext4_orphan_del (handle, inode); +ext4_journal_stop (handle); + } } static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
@@ -372,31 +349,22 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,loff_t pos = iocb->ki_pos;struct inode *inode =file_inode (iocb->ki_filp); +if (!error && size && flags &IOMAP_DIO_UNWRITTEN ) + error =ext4_convert_unwritten_extents (NULL , inode, pos, size);if (error)return error; - -if (size && flags &IOMAP_DIO_UNWRITTEN ) { - error =ext4_convert_unwritten_extents (NULL , inode, pos, size); -if (error <0 ) -return error; - }/* -* If we are extending the file, we have to update i_size here before -* page cache gets invalidated in iomap_dio_rw(). Otherwise racing -* buffered reads could zero out too much from page cache pages. Update -* of on-disk size will happen later in ext4_dio_write_iter() where -* we have enough information to also perform orphan list handling etc. -* Note that we perform all extending writes synchronously under -* i_rwsem held exclusively so i_size update is safe here in that case. -* If the write was not extending, we cannot see pos > i_size here -* because operations reducing i_size like truncate wait for all -* outstanding DIO before updating i_size. +* Note that EXT4_I(inode)->i_disksize can get extended up to +* inode->i_size while the I/O was running due to writeback of delalloc +* blocks. But the code in ext4_iomap_alloc() is careful to use +* zeroed/unwritten extents if this is possible; thus we won't leave +* uninitialized blocks in a file even if we didn't succeed in writing +* as much as we intended. */ - pos += size; -if (pos >i_size_read (inode)) -i_size_write (inode, pos); - -return 0 ; +WARN_ON_ONCE (i_size_read (inode) <READ_ONCE (EXT4_I (inode)->i_disksize)); +if (pos + size <=READ_ONCE (EXT4_I (inode)->i_disksize)) +return size; +return ext4_handle_inode_extension (inode, pos, size); }static const struct iomap_dio_ops ext4_dio_write_ops = {
@@ -572,9 +540,16 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from) 0);if (ret == -ENOTBLK ) ret =0 ; - -if (extend) - ret =ext4_handle_inode_extension (inode, offset, ret, count); +if (extend) { +/* +* We always perform extending DIO write synchronously so by +* now the IO is completed and ext4_handle_inode_extension() +* was called. Cleanup the inode in case of error or race with +* writeback of delalloc blocks. +*/ +WARN_ON_ONCE (ret == -EIOCBQUEUED ); +ext4_inode_extension_cleanup (inode, ret); + } out:if (ilock_shared)
@@ -655,8 +630,10 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from) ret =dax_iomap_rw (iocb, from, &ext4_iomap_ops); -if (extend) - ret =ext4_handle_inode_extension (inode, offset, ret, count); +if (extend) { + ret =ext4_handle_inode_extension (inode, offset, ret); +ext4_inode_extension_cleanup (inode, ret); + } out:inode_unlock (inode);if (ret >0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 559/691 ext4: dax: fix overflowing extents beyond inode size when partially writing
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
[ Upstream commit dda898d7ffe85931f9cca6d702a51f33717c501e ]
The dax_iomap_rw() does two things in each iteration: map written blocks and copy user data to blocks. If the process is killed by user(See signal handling in dax_iomap_iter()), the copied data will be returned and added on inode size, which means that the length of written extents may exceed the inode size, then fsck will fail. An example is given as:
dd if=/dev/urandom of=file bs=4M count=1
dax_iomap_rw
iomap_iter // round 1
ext4_iomap_begin
ext4_iomap_alloc // allocate 0~2M extents(written flag)
dax_iomap_iter // copy 2M data
iomap_iter // round 2
iomap_iter_advance
iter->pos += iter->processed // iter->pos = 2M
ext4_iomap_begin
ext4_iomap_alloc // allocate 2~4M extents(written flag)
dax_iomap_iter
fatal_signal_pending
done = iter->pos - iocb->ki_pos // done = 2M
ext4_handle_inode_extension
ext4_update_inode_size // inode size = 2M
fsck reports: Inode 13, i_size is 2097152, should be 4194304. Fix?
Fix the problem by truncating extents if the written length is smaller than expected.
--- fs/ext4/file.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ext4/file.c +4 -4
@@ -307,10 +307,10 @@ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,* Clean up the inode after DIO or DAX extending write has completed and the * inode size has been updated using ext4_handle_inode_extension(). */ -static void ext4_inode_extension_cleanup (struct inode *inode,ssize_t count) +static void ext4_inode_extension_cleanup (struct inode *inode,bool need_trunc) {lockdep_assert_held_write (&inode->i_rwsem); -if (count <0 ) { +if (need_trunc) {ext4_truncate_failed_write (inode);/* * If the truncate operation failed early, then the inode may
@@ -548,7 +548,7 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)* writeback of delalloc blocks. */ WARN_ON_ONCE (ret == -EIOCBQUEUED ); -ext4_inode_extension_cleanup (inode, ret); +ext4_inode_extension_cleanup (inode, ret <0 ); } out:
@@ -632,7 +632,7 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)if (extend) { ret =ext4_handle_inode_extension (inode, offset, ret); -ext4_inode_extension_cleanup (inode, ret); +ext4_inode_extension_cleanup (inode, ret < (ssize_t )count); } out:inode_unlock (inode);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 560/691 arm64: Add Cortex-715 CPU part definition
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anshuman Khandual <[email protected]>
[ Upstream commit 07e39e60bbf0ccd5f895568e1afca032193705c0 ]
Add the CPU Partnumbers for the new Arm designs.
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -82,6 +82,7 @@#define ARM_CPU_PART_CORTEX_A510 0xD46#define ARM_CPU_PART_CORTEX_A520 0xD80#define ARM_CPU_PART_CORTEX_A710 0xD47 +#define ARM_CPU_PART_CORTEX_A715 0xD4D#define ARM_CPU_PART_CORTEX_X2 0xD48#define ARM_CPU_PART_NEOVERSE_N2 0xD49#define ARM_CPU_PART_CORTEX_A78C 0xD4B
@@ -144,6 +145,7 @@#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) +#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 561/691 arm64: cputype: Add Neoverse-N3 definitions
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 924725707d80bc2588cefafef76ff3f164d299bc ]
Add cputype definitions for Neoverse-N3. These will be used for errata detection in subsequent patches.
These values can be found in Table A-261 ("MIDR_EL1 bit descriptions") in issue 02 of the Neoverse-N3 TRM, which can be found at:
https://developer.arm.com/documentation/107997/0000/?lang=en
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -94,6 +94,7 @@#define ARM_CPU_PART_NEOVERSE_V3 0xD84#define ARM_CPU_PART_CORTEX_X925 0xD85#define ARM_CPU_PART_CORTEX_A725 0xD87 +#define ARM_CPU_PART_NEOVERSE_N3 0xD8E#define APM_CPU_PART_POTENZA 0x000
@@ -157,6 +158,7 @@#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) +#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 562/691 arm64: errata: Expand speculative SSBS workaround once more
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 081eb7932c2b244f63317a982c5e3990e2c7fbdd ]
A number of Arm Ltd CPUs suffer from errata whereby an MSR to the SSBS special-purpose register does not affect subsequent speculative instructions, permitting speculative store bypassing for a window of time.
We worked around this for a number of CPUs in commits:
* 7187bb7d0b5c7dfa ("arm64: errata: Add workaround for Arm errata 3194386 and 3312417")
* 75b3c43eab594bfb ("arm64: errata: Expand speculative SSBS workaround")
* 145502cac7ea70b5 ("arm64: errata: Expand speculative SSBS workaround (again)")
Since then, a (hopefully final) batch of updates have been published, with two more affected CPUs. For the affected CPUs the existing mitigation is sufficient, as described in their respective Software Developer Errata Notice (SDEN) documents:
* Cortex-A715 (MP148) SDEN v15.0, erratum 3456084
https://developer.arm.com/documentation/SDEN-2148827/1500/
* Neoverse-N3 (MP195) SDEN v5.0, erratum 3456111
https://developer.arm.com/documentation/SDEN-3050973/0500/
Enable the existing mitigation by adding the relevant MIDRs to erratum_spec_ssbs_list, and update silicon-errata.rst and the Kconfig text accordingly.
--- Documentation/arm64/silicon-errata.rst | 4 ++++ arch/arm64/Kconfig | 2 ++ arch/arm64/kernel/cpu_errata.c | 2 ++ 3 files changed, 8 insertions(+)
Documentation/arm64/silicon-errata.rst +4 -0
@@ -118,6 +118,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
@@ -150,6 +152,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
arch/arm64/Kconfig +2 -0
@@ -860,6 +860,7 @@ config ARM64_ERRATUM_3194386 * ARM Cortex-A78C erratum 3324346 * ARM Cortex-A78C erratum 3324347 * ARM Cortex-A710 erratam 3324338 + * ARM Cortex-A715 errartum 3456084 * ARM Cortex-A720 erratum 3456091 * ARM Cortex-A725 erratum 3456106 * ARM Cortex-X1 erratum 3324344
@@ -870,6 +871,7 @@ config ARM64_ERRATUM_3194386 * ARM Cortex-X925 erratum 3324334 * ARM Neoverse-N1 erratum 3324349 * ARM Neoverse N2 erratum 3324339 + * ARM Neoverse-N3 erratum 3456111 * ARM Neoverse-V1 erratum 3324341 * ARM Neoverse V2 erratum 3324336 * ARM Neoverse-V3 erratum 3312417
arch/arm64/kernel/cpu_errata.c +2 -0
@@ -409,6 +409,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {MIDR_ALL_VERSIONS (MIDR_CORTEX_A78 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A78C ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A710 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_A715 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A720 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A725 ), MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
@@ -419,6 +420,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {MIDR_ALL_VERSIONS (MIDR_CORTEX_X925 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N1 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ), +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N3 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V1 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V2 ), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 563/691 uprobes: fix kernel info leak via "[uprobes]" vma
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov <[email protected]>
commit 34820304cc2cd1804ee1f8f3504ec77813d29c8e upstream.
xol_add_vma() maps the uninitialized page allocated by __create_xol_area() into userspace. On some architectures (x86) this memory is readable even without VM_READ, VM_EXEC results in the same pgprot_t as VM_EXEC|VM_READ, although this doesn't really matter, debugger can read this memory anyway.
--- kernel/events/uprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/uprobes.c +1 -1
@@ -1495,7 +1495,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) area->xol_mapping.name ="[uprobes]" ; area->xol_mapping.pages = area->pages; - area->pages[0 ] =alloc_page (GFP_HIGHUSER ); + area->pages[0 ] =alloc_page (GFP_HIGHUSER | __GFP_ZERO);if (!area->pages[0 ]) goto free_bitmap; area->pages[1 ] =NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 564/691 drm/amd/display: Allow backlight to go below `AMDGPU_DM_DEFAULT_MIN_BACKLIGHT`
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit 87d749a6aab73d8069d0345afaa98297816cb220 ]
The issue with panel power savings compatibility below AMDGPU_DM_DEFAULT_MIN_BACKLIGHT happens at AMDGPU_DM_DEFAULT_MIN_BACKLIGHT as well.
That issue will be fixed separately, so don't prevent the backlight brightness from going that low.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -3936,7 +3936,7 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm,int spread = caps.max_input_signal - caps.min_input_signal;if (caps.max_input_signal >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || - caps.min_input_signal <AMDGPU_DM_DEFAULT_MIN_BACKLIGHT || + caps.min_input_signal <0 || spread >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || spread <AMDGPU_DM_MIN_SPREAD ) { DRM_DEBUG_KMS("DM: Invalid backlight caps: min=%d, max=%d\n",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 565/691 build-id: require program headers to be right after ELF header
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Dobriyan <[email protected]>
[ Upstream commit 961a2851324561caed579764ffbee3db82b32829 ]
Neither ELF spec not ELF loader require program header to be placed right after ELF header, but build-id code very much assumes such placement:
See
find_get_page(vma->vm_file->f_mapping, 0);
line and checks against PAGE_SIZE.
Returns errors for now until someone rewrites build-id parser to be more inline with load_elf_binary().
Stable-dep-of: 905415ff3ffb ("lib/buildid: harden build ID parsing logic")
--- lib/buildid.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
lib/buildid.c +14 -0
@@ -73,6 +73,13 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id,Elf32_Phdr *phdr;int i; +/* +* FIXME +* Neither ELF spec nor ELF loader require that program headers +* start immediately after ELF header. +*/ +if (ehdr->e_phoff !=sizeof (Elf32_Ehdr)) +return -EINVAL ;/* only supports phdr that fits in one page */ if (ehdr->e_phnum > (PAGE_SIZE -sizeof (Elf32_Ehdr)) /sizeof (Elf32_Phdr))
@@ -98,6 +105,13 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id,Elf64_Phdr *phdr;int i; +/* +* FIXME +* Neither ELF spec nor ELF loader require that program headers +* start immediately after ELF header. +*/ +if (ehdr->e_phoff !=sizeof (Elf64_Ehdr)) +return -EINVAL ;/* only supports phdr that fits in one page */ if (ehdr->e_phnum > (PAGE_SIZE -sizeof (Elf64_Ehdr)) /sizeof (Elf64_Phdr))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 566/691 lib/buildid: harden build ID parsing logic
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit 905415ff3ffb1d7e5afa62bacabd79776bd24606 ]
Harden build ID parsing logic, adding explicit READ_ONCE() where it's important to have a consistent value read and validated just once.
Also, as pointed out by Andi Kleen, we need to make sure that entire ELF note is within a page bounds, so move the overflow check up and add an extra note_size boundaries validation.
Fixes tag below points to the code that moved this code into lib/buildid.c, and then subsequently was used in perf subsystem, making this code exposed to perf_event_open() users in v5.12+.
--- lib/buildid.c | 76 +++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 32 deletions(-)
lib/buildid.c +44 -32
@@ -18,31 +18,37 @@ static int parse_build_id_buf(unsigned char *build_id,const void *note_start, Elf32_Word note_size) { - Elf32_Word note_offs = 0, new_offs; - -while (note_offs +sizeof (Elf32_Nhdr) < note_size) { -Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs); + const char note_name[] = "GNU"; +const size_t note_name_sz =sizeof (note_name); +u64 note_off =0 , new_off, name_sz, desc_sz; +const char *data; + +while (note_off +sizeof (Elf32_Nhdr) < note_size && + note_off +sizeof (Elf32_Nhdr) > note_off/* overflow */ ) { +Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_off); + + name_sz =READ_ONCE (nhdr->n_namesz); + desc_sz =READ_ONCE (nhdr->n_descsz); + + new_off = note_off +sizeof (Elf32_Nhdr); +if (check_add_overflow (new_off,ALIGN (name_sz,4 ), &new_off) || +check_add_overflow (new_off,ALIGN (desc_sz,4 ), &new_off) || + new_off > note_size) +break ;if (nhdr->n_type ==BUILD_ID && - nhdr->n_namesz ==sizeof ("GNU" ) && - !strcmp ((char *)(nhdr +1 ),"GNU" ) && - nhdr->n_descsz >0 && - nhdr->n_descsz <=BUILD_ID_SIZE_MAX ) { -memcpy (build_id, - note_start + note_offs + -ALIGN (sizeof ("GNU" ),4 ) +sizeof (Elf32_Nhdr), - nhdr->n_descsz); -memset (build_id + nhdr->n_descsz,0 , -BUILD_ID_SIZE_MAX - nhdr->n_descsz); + name_sz == note_name_sz && +memcmp (nhdr +1 , note_name, note_name_sz) ==0 && + desc_sz >0 && desc_sz <=BUILD_ID_SIZE_MAX ) { + data = note_start + note_off +ALIGN (note_name_sz,4 ); +memcpy (build_id, data, desc_sz); +memset (build_id + desc_sz,0 ,BUILD_ID_SIZE_MAX - desc_sz);if (size) - *size = nhdr->n_descsz; + *size = desc_sz;return 0 ; } - new_offs = note_offs +sizeof (Elf32_Nhdr) + -ALIGN (nhdr->n_namesz,4 ) +ALIGN (nhdr->n_descsz,4 ); -if (new_offs <= note_offs)/* overflow */ -break ; - note_offs = new_offs; + + note_off = new_off; }return -EINVAL ;
@@ -71,7 +77,7 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id, {Elf32_Ehdr *ehdr = (Elf32_Ehdr *)page_addr;Elf32_Phdr *phdr; -int i; +__u32 i, phnum;/* * FIXME
@@ -80,18 +86,19 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id,*/ if (ehdr->e_phoff !=sizeof (Elf32_Ehdr))return -EINVAL ; + + phnum =READ_ONCE (ehdr->e_phnum);/* only supports phdr that fits in one page */ -if (ehdr->e_phnum > - (PAGE_SIZE -sizeof (Elf32_Ehdr)) /sizeof (Elf32_Phdr)) +if (phnum > (PAGE_SIZE -sizeof (Elf32_Ehdr)) /sizeof (Elf32_Phdr))return -EINVAL ; phdr = (Elf32_Phdr *)(page_addr +sizeof (Elf32_Ehdr)); -for (i =0 ; i < ehdr->e_phnum; ++i) { +for (i =0 ; i < phnum; ++i) {if (phdr[i].p_type ==PT_NOTE && !parse_build_id (page_addr, build_id, size, - page_addr + phdr[i].p_offset, - phdr[i].p_filesz)) + page_addr +READ_ONCE (phdr[i].p_offset), +READ_ONCE (phdr[i].p_filesz)))return 0 ; }return -EINVAL ;
@@ -103,7 +110,7 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id, {Elf64_Ehdr *ehdr = (Elf64_Ehdr *)page_addr;Elf64_Phdr *phdr; -int i; +__u32 i, phnum;/* * FIXME
@@ -112,18 +119,19 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id,*/ if (ehdr->e_phoff !=sizeof (Elf64_Ehdr))return -EINVAL ; + + phnum =READ_ONCE (ehdr->e_phnum);/* only supports phdr that fits in one page */ -if (ehdr->e_phnum > - (PAGE_SIZE -sizeof (Elf64_Ehdr)) /sizeof (Elf64_Phdr)) +if (phnum > (PAGE_SIZE -sizeof (Elf64_Ehdr)) /sizeof (Elf64_Phdr))return -EINVAL ; phdr = (Elf64_Phdr *)(page_addr +sizeof (Elf64_Ehdr)); -for (i =0 ; i < ehdr->e_phnum; ++i) { +for (i =0 ; i < phnum; ++i) {if (phdr[i].p_type ==PT_NOTE && !parse_build_id (page_addr, build_id, size, - page_addr + phdr[i].p_offset, - phdr[i].p_filesz)) + page_addr +READ_ONCE (phdr[i].p_offset), +READ_ONCE (phdr[i].p_filesz)))return 0 ; }return -EINVAL ;
@@ -152,6 +160,10 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, page =find_get_page (vma->vm_file->f_mapping,0 );if (!page)return -EFAULT ;/* page not mapped */ +if (!PageUptodate (page)) { +put_page (page); +return -EFAULT ; + } ret = -EINVAL ; page_addr =kmap_atomic (page);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 567/691 drm/rockchip: define gamma registers for RK3399
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugh Cole-Baker <[email protected]>
[ Upstream commit 3ba000d6ae999b99f29afd64814877a5c4406786 ]
The VOP on RK3399 has a different approach from previous versions for setting a gamma lookup table, using an update_gamma_lut register. As this differs from RK3288, give RK3399 its own set of "common" register definitions.
Stable-dep-of: 6b44aa559d6c ("drm/rockchip: vop: clear DMA stop bit on RK3066")
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 ++ drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 24 +++++++++++++++++++-- drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop.h +2 -0
@@ -99,6 +99,8 @@ struct vop_common {struct vop_reg dither_down_en;struct vop_reg dither_up;struct vop_reg dsp_lut_en; +struct vop_reg update_gamma_lut; +struct vop_reg lut_buffer_index;struct vop_reg gate_en;struct vop_reg mmu_en;struct vop_reg out_mode;
drivers/gpu/drm/rockchip/rockchip_vop_reg.c +22 -2
@@ -865,6 +865,24 @@ static const struct vop_output rk3399_output = { .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3), }; +static const struct vop_common rk3399_common = { + .standby =VOP_REG_SYNC (RK3399_SYS_CTRL ,0x1 ,22 ), + .gate_en =VOP_REG (RK3399_SYS_CTRL ,0x1 ,23 ), + .mmu_en =VOP_REG (RK3399_SYS_CTRL ,0x1 ,20 ), + .dither_down_sel =VOP_REG (RK3399_DSP_CTRL1 ,0x1 ,4 ), + .dither_down_mode =VOP_REG (RK3399_DSP_CTRL1 ,0x1 ,3 ), + .dither_down_en =VOP_REG (RK3399_DSP_CTRL1 ,0x1 ,2 ), + .pre_dither_down =VOP_REG (RK3399_DSP_CTRL1 ,0x1 ,1 ), + .dither_up =VOP_REG (RK3399_DSP_CTRL1 ,0x1 ,6 ), + .dsp_lut_en =VOP_REG (RK3399_DSP_CTRL1 ,0x1 ,0 ), + .update_gamma_lut =VOP_REG (RK3399_DSP_CTRL1 ,0x1 ,7 ), + .lut_buffer_index =VOP_REG (RK3399_DBG_POST_REG1 ,0x1 ,1 ), + .data_blank =VOP_REG (RK3399_DSP_CTRL0 ,0x1 ,19 ), + .dsp_blank =VOP_REG (RK3399_DSP_CTRL0 ,0x3 ,18 ), + .out_mode =VOP_REG (RK3399_DSP_CTRL0 ,0xf ,0 ), + .cfg_done =VOP_REG_SYNC (RK3399_REG_CFG_DONE ,0x1 ,0 ), +}; +static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = { .y2r_coefficients = {VOP_REG (RK3399_WIN0_YUV2YUV_Y2R +0 ,0xffff ,0 ),
@@ -946,7 +964,7 @@ static const struct vop_data rk3399_vop_big = { .version = VOP_VERSION(3, 5), .feature = VOP_FEATURE_OUTPUT_RGB10, .intr = &rk3366_vop_intr, - .common = &rk3288_common, + .common = &rk3399_common, .modeset = &rk3288_modeset, .output = &rk3399_output, .afbc = &rk3399_vop_afbc,
@@ -954,6 +972,7 @@ static const struct vop_data rk3399_vop_big = { .win = rk3399_vop_win_data, .win_size = ARRAY_SIZE(rk3399_vop_win_data), .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data, + .lut_size = 1024, };static const struct vop_win_data rk3399_vop_lit_win_data[] = {
@@ -972,13 +991,14 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {static const struct vop_data rk3399_vop_lit = { .version =VOP_VERSION (3 ,6 ), .intr = &rk3366_vop_intr, - .common = &rk3288_common, + .common = &rk3399_common, .modeset = &rk3288_modeset, .output = &rk3399_output, .misc = &rk3368_misc, .win = rk3399_vop_lit_win_data, .win_size =ARRAY_SIZE (rk3399_vop_lit_win_data), .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data, + .lut_size =256 , };static const struct vop_win_data rk3228_vop_win_data[] = {
drivers/gpu/drm/rockchip/rockchip_vop_reg.h +1 -0
@@ -628,6 +628,7 @@#define RK3399_YUV2YUV_WIN 0x02c0#define RK3399_YUV2YUV_POST 0x02c4#define RK3399_AUTO_GATING_EN 0x02cc +#define RK3399_DBG_POST_REG1 0x036c#define RK3399_WIN0_CSC_COE 0x03a0#define RK3399_WIN1_CSC_COE 0x03c0#define RK3399_WIN2_CSC_COE 0x03e0
Signature · 1 line
2.43.0