Hi community.
Previously our team reported a race condition in IMA relates to LSM
based rules which would case IMA to match files that should be filtered
out under normal condition. The issue was originally analyzed and fixed
on mainstream. The patch and the discussion could be found here:
https://lore.kernel.org/all/20220921125804.59490-1-guozihua@huawei.com/
After that, we did a regression test on 4.19 LTS and the same issue
arises. Further analysis reveled that the issue is from a completely
different cause.
The cause is that selinux_audit_rule_init() would set the rule (which is
a second level pointer) to NULL immediately after called. The relevant
codes are as shown:
security/selinux/ss/services.c:
> int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
> {
> struct selinux_state *state = &selinux_state;
> struct policydb *policydb = &state->ss->policydb;
> struct selinux_audit_rule *tmprule;
> struct role_datum *roledatum;
> struct type_datum *typedatum;
> struct user_datum *userdatum;
> struct selinux_audit_rule **rule = (struct selinux_audit_rule **)vrule;
> int rc = 0;
>
> *rule = NULL;
*rule is set to NULL here, which means the rule on IMA side is also NULL.
>
> if (!state->initialized)
> return -EOPNOTSUPP;
...
> out:
> read_unlock(&state->ss->policy_rwlock);
>
> if (rc) {
> selinux_audit_rule_free(tmprule);
> tmprule = NULL;
> }
>
> *rule = tmprule;
rule is updated at the end of the function.
>
> return rc;
> }
security/integrity/ima/ima_policy.c:
> static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
> const struct cred *cred, u32 secid,
> enum ima_hooks func, int mask)
> {...
> for (i = 0; i < MAX_LSM_RULES; i++) {
> int rc = 0;
> u32 osid;
> int retried = 0;
>
> if (!rule->lsm[i].rule)
> continue;
Setting rule to NULL would lead to LSM based rule matching being skipped.
> retry:
> switch (i) {
To solve this issue, there are multiple approaches we might take and I
would like some input from the community.
The first proposed solution would be to change
selinux_audit_rule_init(). Remove the set to NULL bit and update the
rule pointer with cmpxchg.
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index a9f2bc8443bd..aa74b04ccaf7 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -3297,10 +3297,9 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
> struct type_datum *typedatum;
> struct user_datum *userdatum;
> struct selinux_audit_rule **rule = (struct selinux_audit_rule **)vrule;
> + struct selinux_audit_rule *orig = rule;
> int rc = 0;
>
> - *rule = NULL;
> -
> if (!state->initialized)
> return -EOPNOTSUPP;
>
> @@ -3382,7 +3381,8 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
> tmprule = NULL;
> }
>
> - *rule = tmprule;
> + if (cmpxchg(rule, orig, tmprule) != orig)
> + selinux_audit_rule_free(tmprule);
>
> return rc;
> }
This solution would be an easy fix, but might influence other modules
calling selinux_audit_rule_init() directly or indirectly (on 4.19 LTS,
only auditfilter and IMA it seems). And it might be worth returning an
error code such as -EAGAIN.
Or, we can access rules via RCU, similar to what we do on 5.10. This
could means more code change and testing.
Reported-by: Huaxin Lu <luhuaxin1(a)huawei.com>
--
Best
GUO Zihua
The primary task of the onboard_usb_hub driver is to control the
power of an onboard USB hub. The driver gets the regulator from the
device tree property "vdd-supply" of the hub's DT node. Some boards
have device tree nodes for USB hubs supported by this driver, but
don't specify a "vdd-supply". This is not an error per se, it just
means that the onboard hub driver can't be used for these hubs, so
don't create platform devices for such nodes.
This change doesn't completely fix the reported regression. It
should fix it for the RPi 3 B Plus and boards with similar hub
configurations (compatible DT nodes without "vdd-supply"), boards
that actually use the onboard hub driver could still be impacted
by the race conditions discussed in that thread. Not creating the
platform devices for nodes without "vdd-supply" is the right
thing to do, independently from the race condition, which will
be fixed in future patch.
Fixes: 8bc063641ceb ("usb: misc: Add onboard_usb_hub driver")
Link: https://lore.kernel.org/r/d04bcc45-3471-4417-b30b-5cf9880d785d@i2se.com/
Reported-by: Stefan Wahren <stefan.wahren(a)i2se.com>
Signed-off-by: Matthias Kaehlcke <mka(a)chromium.org>
---
Changes in v2:
- don't create platform devices when "vdd-supply" is missing,
rather than returning an error from _find_onboard_hub()
- check for "vdd-supply" not "vdd" (Johan)
- updated subject and commit message
- added 'Link' tag (regzbot)
drivers/usb/misc/onboard_usb_hub_pdevs.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/usb/misc/onboard_usb_hub_pdevs.c b/drivers/usb/misc/onboard_usb_hub_pdevs.c
index ed22a18f4ab7..8cea53b0907e 100644
--- a/drivers/usb/misc/onboard_usb_hub_pdevs.c
+++ b/drivers/usb/misc/onboard_usb_hub_pdevs.c
@@ -101,6 +101,19 @@ void onboard_hub_create_pdevs(struct usb_device *parent_hub, struct list_head *p
}
}
+ /*
+ * The primary task of the onboard_usb_hub driver is to control
+ * the power of an USB onboard hub. Some boards have device tree
+ * nodes for USB hubs supported by this driver, but don't
+ * specify a "vdd-supply", which is needed by the driver. This is
+ * not a DT error per se, it just means that the onboard hub
+ * driver can't be used with these nodes, so don't create a
+ * a platform device for such a node.
+ */
+ if (!of_get_property(np, "vdd-supply", NULL) &&
+ !of_get_property(npc, "vdd-supply", NULL))
+ goto node_put;
+
pdev = of_platform_device_create(np, NULL, &parent_hub->dev);
if (!pdev) {
dev_err(&parent_hub->dev,
--
2.39.0.314.g84b9a713c41-goog
During suspend and resume, the channel state needs to be saved locally.
Otherwise, the endpoint may access the channels while they were being
suspended and causing access violations.
Fix it by saving the channel state locally during suspend and resume.
Cc: <stable(a)vger.kernel.org> # 5.19
Fixes: e4b7b5f0f30a ("bus: mhi: ep: Add support for suspending and resuming channels")
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam(a)linaro.org>
---
drivers/bus/mhi/ep/main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index 2362fcc8b32c..bcaaba97ef63 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -1122,6 +1122,7 @@ void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl)
dev_dbg(&mhi_chan->mhi_dev->dev, "Suspending channel\n");
/* Set channel state to SUSPENDED */
+ mhi_chan->state = MHI_CH_STATE_SUSPENDED;
tmp &= ~CHAN_CTX_CHSTATE_MASK;
tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_SUSPENDED);
mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp);
@@ -1151,6 +1152,7 @@ void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl)
dev_dbg(&mhi_chan->mhi_dev->dev, "Resuming channel\n");
/* Set channel state to RUNNING */
+ mhi_chan->state = MHI_CH_STATE_RUNNING;
tmp &= ~CHAN_CTX_CHSTATE_MASK;
tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_RUNNING);
mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp);
--
2.25.1
There is a good chance that while the channel ring gets processed, the STOP
or RESET command for the channel might be received from the MHI host. In
those cases, the entire channel ring processing needs to be protected by
chan->lock to prevent the race where the corresponding channel ring might
be reset.
While at it, let's also add a sanity check to make sure that the ring is
started before processing it. Because, if the STOP/RESET command gets
processed while mhi_ep_ch_ring_worker() waited for chan->lock, the ring
would've been reset.
Cc: <stable(a)vger.kernel.org> # 5.19
Fixes: 03c0bb8ec983 ("bus: mhi: ep: Add support for processing channel rings")
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam(a)linaro.org>
---
drivers/bus/mhi/ep/main.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index 0bce6610ebf1..2362fcc8b32c 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -730,24 +730,37 @@ static void mhi_ep_ch_ring_worker(struct work_struct *work)
list_del(&itr->node);
ring = itr->ring;
+ chan = &mhi_cntrl->mhi_chan[ring->ch_id];
+ mutex_lock(&chan->lock);
+
+ /*
+ * The ring could've stopped while we waited to grab the (chan->lock), so do
+ * a sanity check before going further.
+ */
+ if (!ring->started) {
+ mutex_unlock(&chan->lock);
+ kfree(itr);
+ continue;
+ }
+
/* Update the write offset for the ring */
ret = mhi_ep_update_wr_offset(ring);
if (ret) {
dev_err(dev, "Error updating write offset for ring\n");
+ mutex_unlock(&chan->lock);
kfree(itr);
continue;
}
/* Sanity check to make sure there are elements in the ring */
if (ring->rd_offset == ring->wr_offset) {
+ mutex_unlock(&chan->lock);
kfree(itr);
continue;
}
el = &ring->ring_cache[ring->rd_offset];
- chan = &mhi_cntrl->mhi_chan[ring->ch_id];
- mutex_lock(&chan->lock);
dev_dbg(dev, "Processing the ring for channel (%u)\n", ring->ch_id);
ret = mhi_ep_process_ch_ring(ring, el);
if (ret) {
--
2.25.1
From: Francesco Dolcini <francesco.dolcini(a)toradex.com>
Add a fallback mechanism to handle the case in which #size-cells is set
to <0>. According to the DT binding the nand controller node should have
set it to 0 and this is not compatible with the legacy way of
specifying partitions directly as child nodes of the nand-controller node.
This fixes a boot failure on colibri-imx7 and potentially other boards.
Cc: stable(a)vger.kernel.org
Fixes: 753395ea1e45 ("ARM: dts: imx7: Fix NAND controller size-cells")
Link: https://lore.kernel.org/all/Y4dgBTGNWpM6SQXI@francesco-nb.int.toradex.com/
Signed-off-by: Francesco Dolcini <francesco.dolcini(a)toradex.com>
---
drivers/mtd/parsers/ofpart_core.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/mtd/parsers/ofpart_core.c b/drivers/mtd/parsers/ofpart_core.c
index 192190c42fc8..aa3b7fa61e50 100644
--- a/drivers/mtd/parsers/ofpart_core.c
+++ b/drivers/mtd/parsers/ofpart_core.c
@@ -122,6 +122,17 @@ static int parse_fixed_partitions(struct mtd_info *master,
a_cells = of_n_addr_cells(pp);
s_cells = of_n_size_cells(pp);
+ if (s_cells == 0) {
+ /*
+ * Use #size-cells = <1> for backward compatibility
+ * in case #size-cells is set to <0> and firmware adds
+ * OF partitions without setting it.
+ */
+ pr_warn_once("%s: ofpart partition %pOF (%pOF) #size-cells is <0>, using <1> for backward compatibility.\n",
+ master->name, pp,
+ mtd_node);
+ s_cells = 1;
+ }
if (len / 4 != a_cells + s_cells) {
pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n",
master->name, pp,
--
2.25.1
The series is intended for stable(a)vger.kernel.org # 5.4+
Syzkaller reported the following bug on linux-5.{4, 10, 15}.y:
https://syzkaller.appspot.com/bug?id=ce5575575f074c33ff80d104f5baee26f22e95…
The upstream commit that introduces this bug is:
1ed1d5921139 ("net: skip virtio_net_hdr_set_proto if protocol already set")
Upstream fixes the bug with the following commits, one of which introduces
new support:
e9d3f80935b6 ("net/af_packet: make sure to pull mac header")
dfed913e8b55 ("net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO")
The additional logic and risk backported seems manageable.
The blammed commit introduces a kernel BUG in __skb_gso_segment for
AF_PACKET SOCK_RAW GSO VLAN tagged packets. What happens is that
virtio_net_hdr_set_proto() exists early as skb->protocol is already set to
ETH_P_ALL. Then in packet_parse_headers() skb->protocol is set to
ETH_P_8021AD, but neither the network header position is adjusted, nor the
mac header is pulled. Thus when we get to validate the xmit skb and enter
skb_mac_gso_segment(), skb->mac_len has value 14, but vlan_depth gets
updated to 18 after skb_network_protocol() is called. This causes the
BUG_ON from __skb_pull(skb, vlan_depth) to be hit, as the mac header has
not been pulled yet.
The fixes from upstream backported cleanly without conflicts. I updated
the commit message of the first patch to describe the problem encountered,
and added Cc, Fixes, Reported-by and Tested-by tags. For the second patch
I just added Cc to stable indicating the versions to be fixed, and added
my Tested and Signed-off-by tags.
I tested the patches on linux-5.{4, 10, 15}.y.
Eric Dumazet (1):
net/af_packet: make sure to pull mac header
Hangbin Liu (1):
net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO
net/packet/af_packet.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
--
2.34.1
SVACE reports always true condition issue at
tl92d_phy_reload_iqk_setting() in 5.10 stable releases. The problem has
been fixed by the following patches which can be cleanly applied to the
5.10 branch.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Stable team,
Please backport these upstream commits to stable kernels:
- c7423dbdbc9e ("ima: Handle -ESTALE returned by
ima_filter_rule_match()"
Dependency on:
- d57378d3aa4d ("ima: Simplify ima_lsm_copy_rule")
Known minor merge conflicts:
- Commit: 65603435599f ("ima: Fix trivial typos in the comments") fixed
"refrences" spelling, causes a merge conflict.
- Commit 28073eb09c5a ("ima: Fix fall-through warnings for Clang") adds
a "break;" before "default:", causes a merge conflict.
Simplifies backporting to linux-5.4.y:
- 465aee77aae8 ("ima: Free the entire rule when deleting a list of
rules")
except for the line "kfree(entry->keyrings);" - introduced in 5.6.y.
- 39e5993d0d45 ("ima: Shallow copy the args_p member of
ima_rule_entry.lsm elements")
- b8867eedcf76 ("ima: Rename internal filter rule functions")
- f60c826d0318 ("ima: Use kmemdup rather than kmalloc+memcpy")
A patch for kernels prior to commit b16942455193 ("ima: use the lsm
policy
update notifier") will be posted separately.
thanks,
Mimi
From: Andreas Rammhold <andreas(a)rammhold.de>
If memory has been found early_init_dt_scan_memory now returns 1. If
it hasn't found any memory it will return 0, allowing other memory
setup mechanisms to carry on.
Previously early_init_dt_scan_memory always returned 0 without
distinguishing between any kind of memory setup being done or not. Any
code path after the early_init_dt_scan memory call in the ramips
plat_mem_setup code wouldn't be executed anymore. Making
early_init_dt_scan_memory the only way to initialize the memory.
Some boards, including my mt7621 based Cudy X6 board, depend on memory
initialization being done via the soc_info.mem_detect function
pointer. Those wouldn't be able to obtain memory and panic the kernel
during early bootup with the message "early_init_dt_alloc_memory_arch:
Failed to allocate 12416 bytes align=0x40".
Fixes: 1f012283e936 ("of/fdt: Rework early_init_dt_scan_memory() to call directly")
Cc: stable(a)vger.kernel.org
Signed-off-by: Andreas Rammhold <andreas(a)rammhold.de>
---
arch/mips/ralink/of.c | 2 +-
drivers/of/fdt.c | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index ea8072acf8d94..6873b02634219 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -63,7 +63,7 @@ void __init plat_mem_setup(void)
dtb = get_fdt();
__dt_setup_arch(dtb);
- if (!early_init_dt_scan_memory())
+ if (early_init_dt_scan_memory())
return;
if (soc_info.mem_detect)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 7b571a6316397..4f88e8bbdd279 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1099,7 +1099,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
*/
int __init early_init_dt_scan_memory(void)
{
- int node;
+ int node, found_memory = 0;
const void *fdt = initial_boot_params;
fdt_for_each_subnode(node, fdt, 0) {
@@ -1139,6 +1139,8 @@ int __init early_init_dt_scan_memory(void)
early_init_dt_add_memory_arch(base, size);
+ found_memory = 1;
+
if (!hotpluggable)
continue;
@@ -1147,7 +1149,7 @@ int __init early_init_dt_scan_memory(void)
base, base + size);
}
}
- return 0;
+ return found_memory;
}
int __init early_init_dt_scan_chosen(char *cmdline)
--
2.38.1
@head_id points to the newest record, but the printing loop
exits when it increments to this value (before printing).
Exit the printing loop after the newest record has been printed.
The python-based function in scripts/gdb/linux/dmesg.py already
does this correctly.
Fixes: e60768311af8 ("scripts/gdb: update for lockless printk ringbuffer")
Cc: stable(a)vger.kernel.org
Signed-off-by: John Ogness <john.ogness(a)linutronix.de>
---
Documentation/admin-guide/kdump/gdbmacros.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kdump/gdbmacros.txt b/Documentation/admin-guide/kdump/gdbmacros.txt
index 82aecdcae8a6..030de95e3e6b 100644
--- a/Documentation/admin-guide/kdump/gdbmacros.txt
+++ b/Documentation/admin-guide/kdump/gdbmacros.txt
@@ -312,10 +312,10 @@ define dmesg
set var $prev_flags = $info->flags
end
- set var $id = ($id + 1) & $id_mask
if ($id == $end_id)
loop_break
end
+ set var $id = ($id + 1) & $id_mask
end
end
document dmesg
base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2
--
2.30.2
When the host controller is not responding, all URBs queued to all
endpoints need to be killed. This can cause a kernel panic if we
dereference an invalid endpoint.
Fix this by using xhci_get_virt_ep() helper to find the endpoint and
checking if the endpoint is valid before dereferencing it.
[233311.853271] xhci-hcd xhci-hcd.1.auto: xHCI host controller not responding, assume dead
[233311.853393] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000e8
[233311.853964] pc : xhci_hc_died+0x10c/0x270
[233311.853971] lr : xhci_hc_died+0x1ac/0x270
[233311.854077] Call trace:
[233311.854085] xhci_hc_died+0x10c/0x270
[233311.854093] xhci_stop_endpoint_command_watchdog+0x100/0x1a4
[233311.854105] call_timer_fn+0x50/0x2d4
[233311.854112] expire_timers+0xac/0x2e4
[233311.854118] run_timer_softirq+0x300/0xabc
[233311.854127] __do_softirq+0x148/0x528
[233311.854135] irq_exit+0x194/0x1a8
[233311.854143] __handle_domain_irq+0x164/0x1d0
[233311.854149] gic_handle_irq.22273+0x10c/0x188
[233311.854156] el1_irq+0xfc/0x1a8
[233311.854175] lpm_cpuidle_enter+0x25c/0x418 [msm_pm]
[233311.854185] cpuidle_enter_state+0x1f0/0x764
[233311.854194] do_idle+0x594/0x6ac
[233311.854201] cpu_startup_entry+0x7c/0x80
[233311.854209] secondary_start_kernel+0x170/0x198
Fixes: 50e8725e7c42 ("xhci: Refactor command watchdog and fix split string.")
Cc: stable(a)vger.kernel.org
Signed-off-by: Jimmy Hu <hhhuuu(a)google.com>
---
drivers/usb/host/xhci-ring.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ddc30037f9ce..f5b0e1ce22af 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1169,7 +1169,10 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci,
struct xhci_virt_ep *ep;
struct xhci_ring *ring;
- ep = &xhci->devs[slot_id]->eps[ep_index];
+ ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+ if (!ep)
+ return;
+
if ((ep->ep_state & EP_HAS_STREAMS) ||
(ep->ep_state & EP_GETTING_NO_STREAMS)) {
int stream_id;
--
2.39.0.314.g84b9a713c41-goog
usb_kill_urb warranties that all the handlers are finished when it
returns, but does not protect against threads that might be handling
asynchronously the urb.
For UVC, the function uvc_ctrl_status_event_async() takes care of
control changes asynchronously.
If the code is executed in the following order:
CPU 0 CPU 1
===== =====
uvc_status_complete()
uvc_status_stop()
uvc_ctrl_status_event_work()
uvc_status_start() -> FAIL
Then uvc_status_start will keep failing and this error will be shown:
<4>[ 5.540139] URB 0000000000000000 submitted while active
drivers/usb/core/urb.c:378 usb_submit_urb+0x4c3/0x528
Let's improve the current situation, by not re-submiting the urb if
we are stopping the status event. Also process the queued work
(if any) during stop.
CPU 0 CPU 1
===== =====
uvc_status_complete()
uvc_status_stop()
uvc_status_start()
uvc_ctrl_status_event_work() -> FAIL
Hopefully, with the usb layer protection this should be enough to cover
all the cases.
Cc: stable(a)vger.kernel.org
Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives")
Reviewed-by: Yunke Cao <yunkec(a)chromium.org>
Signed-off-by: Ricardo Ribalda <ribalda(a)chromium.org>
---
uvc: Fix race condition on uvc
Make sure that all the async work is finished when we stop the status urb.
To: Yunke Cao <yunkec(a)chromium.org>
To: Sergey Senozhatsky <senozhatsky(a)chromium.org>
To: Max Staudt <mstaudt(a)google.com>
To: Laurent Pinchart <laurent.pinchart(a)ideasonboard.com>
To: Mauro Carvalho Chehab <mchehab(a)kernel.org>
Cc: linux-media(a)vger.kernel.org
Cc: linux-kernel(a)vger.kernel.org
---
Changes in v4:
- Replace bool with atomic_t to avoid compiler reordering
- First complete the async work and then kill the urb to avoid race (Thanks Laurent!)
- Link to v3: https://lore.kernel.org/r/20221212-uvc-race-v3-0-954efc752c9a@chromium.org
Changes in v3:
- Remove the patch for dev->status, makes more sense in another series, and makes
the zero day less nervous.
- Update reviewed-by (thanks Yunke!).
- Link to v2: https://lore.kernel.org/r/20221212-uvc-race-v2-0-54496cc3b8ab@chromium.org
Changes in v2:
- Add a patch for not kalloc dev->status
- Redo the logic mechanism, so it also works with suspend (Thanks Yunke!)
- Link to v1: https://lore.kernel.org/r/20221212-uvc-race-v1-0-c52e1783c31d@chromium.org
---
drivers/media/usb/uvc/uvc_ctrl.c | 3 +++
drivers/media/usb/uvc/uvc_status.c | 6 ++++++
drivers/media/usb/uvc/uvcvideo.h | 1 +
3 files changed, 10 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index c95a2229f4fa..1be6897a7d6d 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1442,6 +1442,9 @@ static void uvc_ctrl_status_event_work(struct work_struct *work)
uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
+ if (atomic_read(&dev->flush_status))
+ return;
+
/* Resubmit the URB. */
w->urb->interval = dev->int_ep->desc.bInterval;
ret = usb_submit_urb(w->urb, GFP_KERNEL);
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index 7518ffce22ed..4a95850cdc1b 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -304,10 +304,16 @@ int uvc_status_start(struct uvc_device *dev, gfp_t flags)
if (dev->int_urb == NULL)
return 0;
+ atomic_set(&dev->flush_status, 0);
return usb_submit_urb(dev->int_urb, flags);
}
void uvc_status_stop(struct uvc_device *dev)
{
+ struct uvc_ctrl_work *w = &dev->async_ctrl;
+
+ atomic_set(&dev->flush_status, 1);
+ if (cancel_work_sync(&w->work))
+ uvc_ctrl_status_event(w->chain, w->ctrl, w->data);
usb_kill_urb(dev->int_urb);
}
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index df93db259312..1274691f157f 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -560,6 +560,7 @@ struct uvc_device {
struct usb_host_endpoint *int_ep;
struct urb *int_urb;
u8 *status;
+ atomic_t flush_status;
struct input_dev *input;
char input_phys[64];
---
base-commit: 0ec5a38bf8499f403f81cb81a0e3a60887d1993c
change-id: 20221212-uvc-race-09276ea68bf8
Best regards,
--
Ricardo Ribalda <ribalda(a)chromium.org>
syzbot reported a use-after-free Read in ext4_find_extent that is hit when
using a corrupted file system. The bug was reported on Android 5.15, but
using the same reproducer triggers the bug on v6.2-rc1 as well.
Fix the use-after-free by checking the extent header magic. An alternative
would be to check the values of EXT4_{FIRST,LAST}_{EXTENT,INDEX} used in
ext4_ext_binsearch() and ext4_ext_binsearch_idx(), so that we make sure
that pointers returned by EXT4_{FIRST,LAST}_{EXTENT,INDEX} don't exceed the
bounds of the extent tree node. But this alternative will not squash
the bug for the cases where eh->eh_entries fit into eh->eh_max. We could
also try to check the sanity of the path, but costs more than checking just
the header magic, so stick to the header magic sanity check.
Link: https://syzkaller.appspot.com/bug?id=be6e90ce70987950e6deb3bac8418344ca8b96…
Reported-by: syzbot+0827b4b52b5ebf65f219(a)syzkaller.appspotmail.com
Cc: stable(a)vger.kernel.org
Signed-off-by: Tudor Ambarus <tudor.ambarus(a)linaro.org>
---
v2: drop wrong/uneeded le16_to_cpu() conversion for eh->eh_magic
fs/ext4/extents.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 9de1c9d1a13d..bedc8c098449 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -894,6 +894,12 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
gfp_flags |= __GFP_NOFAIL;
eh = ext_inode_hdr(inode);
+ if (eh->eh_magic != EXT4_EXT_MAGIC) {
+ EXT4_ERROR_INODE(inode, "Extent header has invalid magic.");
+ ret = -EFSCORRUPTED;
+ goto err;
+ }
+
depth = ext_depth(inode);
if (depth < 0 || depth > EXT4_MAX_EXTENT_DEPTH) {
EXT4_ERROR_INODE(inode, "inode has invalid extent depth: %d",
--
2.34.1
These indices should reference the ID placed within the dai_driver
array, not the indices of the array itself.
This fixes commit 4ff028f6c108 ("ASoC: qcom: lpass-cpu: Make I2S SD
lines configurable"), which among others, broke IPQ8064 audio
(sound/soc/qcom/lpass-ipq806x.c) because it uses ID 4 but we'd stop
initializing the mi2s_playback_sd_mode and mi2s_capture_sd_mode arrays
at ID 0.
Fixes: 4ff028f6c108 ("ASoC: qcom: lpass-cpu: Make I2S SD lines configurable")
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Brian Norris <computersforpeace(a)gmail.com>
---
sound/soc/qcom/lpass-cpu.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 54353842dc07..dbdaaa85ce48 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -1037,10 +1037,11 @@ static void of_lpass_cpu_parse_dai_data(struct device *dev,
struct lpass_data *data)
{
struct device_node *node;
- int ret, id;
+ int ret, i, id;
/* Allow all channels by default for backwards compatibility */
- for (id = 0; id < data->variant->num_dai; id++) {
+ for (i = 0; i < data->variant->num_dai; i++) {
+ id = data->variant->dai_driver[i].id;
data->mi2s_playback_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH;
data->mi2s_capture_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH;
}
--
2.39.0