From: "Matthew Wilcox (Oracle)" <willy(a)infradead.org>
stable inclusion
from stable-v5.10.215
commit 8f599ab6fabbca4c741107eade70722a98adfd9f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9Q97O
CVE: CVE-2024-35821
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 723012cab779eee8228376754e22c6594229bf8f ]
Page cache reads are lockless, so setting the freshly allocated page
uptodate before we've overwritten it with the data it's supposed to have
in it will allow a simultaneous reader to see old data. Move the call
to SetPageUptodate into ubifs_write_end(), which is after we copied the
new data into the page.
Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
Cc: stable(a)vger.kernel.org
Signed-off-by: Matthew Wilcox (Oracle) <willy(a)infradead.org>
Reviewed-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Signed-off-by: Richard Weinberger <richard(a)nod.at>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/ubifs/file.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index b35983dff75b..f333ceac67dc 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -262,9 +262,6 @@ static int write_begin_slow(struct address_space *mapping,
return err;
}
}
-
- SetPageUptodate(page);
- ClearPageError(page);
}
if (PagePrivate(page))
@@ -463,9 +460,6 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
return err;
}
}
-
- SetPageUptodate(page);
- ClearPageError(page);
}
err = allocate_budget(c, page, ui, appending);
@@ -475,10 +469,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
* If we skipped reading the page because we were going to
* write all of it, then it is not up to date.
*/
- if (skipped_read) {
+ if (skipped_read)
ClearPageChecked(page);
- ClearPageUptodate(page);
- }
/*
* Budgeting failed which means it would have to force
* write-back but didn't, because we set the @fast flag in the
@@ -569,6 +561,9 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
goto out;
}
+ if (len == PAGE_SIZE)
+ SetPageUptodate(page);
+
if (!PagePrivate(page)) {
attach_page_private(page, (void *)1);
atomic_long_inc(&c->dirty_pg_cnt);
--
2.34.3
From: "Matthew Wilcox (Oracle)" <willy(a)infradead.org>
stable inclusion
from stable-v5.10.215
commit 8f599ab6fabbca4c741107eade70722a98adfd9f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9Q97O
CVE: CVE-2024-35821
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 723012cab779eee8228376754e22c6594229bf8f ]
Page cache reads are lockless, so setting the freshly allocated page
uptodate before we've overwritten it with the data it's supposed to have
in it will allow a simultaneous reader to see old data. Move the call
to SetPageUptodate into ubifs_write_end(), which is after we copied the
new data into the page.
Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
Cc: stable(a)vger.kernel.org
Signed-off-by: Matthew Wilcox (Oracle) <willy(a)infradead.org>
Reviewed-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Signed-off-by: Richard Weinberger <richard(a)nod.at>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
fs/ubifs/file.c
[Conflicting patch fb8bc4c74ae("ubifs: ubifs_writepage: Mark page dirty
after writing inode failed") is not adapted and merged into the current
branch.]
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/ubifs/file.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 1b78f2e09218..25f5548cbc45 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -274,9 +274,6 @@ static int write_begin_slow(struct address_space *mapping,
return err;
}
}
-
- SetPageUptodate(page);
- ClearPageError(page);
}
if (PagePrivate(page))
@@ -475,9 +472,6 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
return err;
}
}
-
- SetPageUptodate(page);
- ClearPageError(page);
}
err = allocate_budget(c, page, ui, appending);
@@ -487,10 +481,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
* If we skipped reading the page because we were going to
* write all of it, then it is not up to date.
*/
- if (skipped_read) {
+ if (skipped_read)
ClearPageChecked(page);
- ClearPageUptodate(page);
- }
/*
* Budgeting failed which means it would have to force
* write-back but didn't, because we set the @fast flag in the
@@ -581,6 +573,9 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
goto out;
}
+ if (len == PAGE_SIZE)
+ SetPageUptodate(page);
+
if (!PagePrivate(page)) {
SetPagePrivate(page);
atomic_long_inc(&c->dirty_pg_cnt);
--
2.34.3
From: Takashi Iwai <tiwai(a)suse.de>
stable inclusion
from stable-v5.10.202
commit 0f5068519f89d928d6c51100e4b274479123829f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9R4N0
CVE: CVE-2023-52754
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit a1766a4fd83befa0b34d932d532e7ebb7fab1fa7 ]
imon driver probes two USB interfaces, and at the probe of the second
interface, the driver assumes blindly that the first interface got
bound with the same imon driver. It's usually true, but it's still
possible that the first interface is bound with another driver via a
malformed descriptor. Then it may lead to a memory corruption, as
spotted by syzkaller; imon driver accesses the data from drvdata as
struct imon_context object although it's a completely different one
that was assigned by another driver.
This patch adds a sanity check -- whether the first interface is
really bound with the imon driver or not -- for avoiding the problem
above at the probe time.
Reported-by: syzbot+59875ffef5cb9c9b29e9(a)syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/000000000000a838aa0603cc74d6@google.com/
Tested-by: Ricardo B. Marliere <ricardo(a)marliere.net>
Link: https://lore.kernel.org/r/20230922005152.163640-1-ricardo@marliere.net
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Sean Young <sean(a)mess.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
drivers/media/rc/imon.c
[Fix context]
Signed-off-by: dinglongwei <dinglongwei1(a)huawei.com>
---
drivers/media/rc/imon.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 6b10363fb6f0..4dfaa791888c 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -2394,6 +2394,12 @@ static int imon_probe(struct usb_interface *interface,
goto fail;
}
+ if (first_if->dev.driver != interface->dev.driver) {
+ dev_err(&interface->dev, "inconsistent driver matching\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
first_if_ctx = usb_get_intfdata(first_if);
if (ifnum == 0) {
--
2.17.1
From: Yang Yingliang <yangyingliang(a)huawei.com>
stable inclusion
from stable-v4.19.215
commit 3dae1a4eced3ee733d7222e69b8a55caf2d61091
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9RD9Z
CVE: CVE-2021-47483
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 55e6d8037805b3400096d621091dfbf713f97e83 upstream.
In regcache_rbtree_insert_to_block(), when 'present' realloc failed,
the 'blk' which is supposed to assign to 'rbnode->block' will be freed,
so 'rbnode->block' points a freed memory, in the error handling path of
regcache_rbtree_init(), 'rbnode->block' will be freed again in
regcache_rbtree_exit(), KASAN will report double-free as follows:
BUG: KASAN: double-free or invalid-free in kfree+0xce/0x390
Call Trace:
slab_free_freelist_hook+0x10d/0x240
kfree+0xce/0x390
regcache_rbtree_exit+0x15d/0x1a0
regcache_rbtree_init+0x224/0x2c0
regcache_init+0x88d/0x1310
__regmap_init+0x3151/0x4a80
__devm_regmap_init+0x7d/0x100
madera_spi_probe+0x10f/0x333 [madera_spi]
spi_probe+0x183/0x210
really_probe+0x285/0xc30
To fix this, moving up the assignment of rbnode->block to immediately after
the reallocation has succeeded so that the data structure stays valid even
if the second reallocation fails.
Reported-by: Hulk Robot <hulkci(a)huawei.com>
Fixes: 3f4ff561bc88b ("regmap: rbtree: Make cache_present bitmap per node")
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
Link: https://lore.kernel.org/r/20211012023735.1632786-1-yangyingliang@huawei.com
Signed-off-by: Mark Brown <broonie(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
drivers/base/regmap/regcache-rbtree.c
[Fix context]
Signed-off-by: dinglongwei <dinglongwei1(a)huawei.com>
---
drivers/base/regmap/regcache-rbtree.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 09580b1448bc..b6f8f4059e25 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -295,14 +295,14 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
if (!blk)
return -ENOMEM;
+ rbnode->block = blk;
+
if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) {
present = krealloc(rbnode->cache_present,
BITS_TO_LONGS(blklen) * sizeof(*present),
map->alloc_flags);
- if (!present) {
- kfree(blk);
+ if (!present)
return -ENOMEM;
- }
memset(present + BITS_TO_LONGS(rbnode->blklen), 0,
(BITS_TO_LONGS(blklen) - BITS_TO_LONGS(rbnode->blklen))
@@ -319,7 +319,6 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
}
/* update the rbnode block, its size and the base register */
- rbnode->block = blk;
rbnode->blklen = blklen;
rbnode->base_reg = base_reg;
rbnode->cache_present = present;
--
2.17.1
From: Jia-Ju Bai <baijiaju(a)buaa.edu.cn>
stable inclusion
from stable-v4.19.299
commit fed492aa6493a91a77ebd51da6fb939c98d94a0d
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9RFRD
CVE: CVE-2023-52855
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit ef307bc6ef04e8c1ea843231db58e3afaafa9fa6 ]
In _dwc2_hcd_urb_enqueue(), "urb->hcpriv = NULL" is executed without
holding the lock "hsotg->lock". In _dwc2_hcd_urb_dequeue():
spin_lock_irqsave(&hsotg->lock, flags);
...
if (!urb->hcpriv) {
dev_dbg(hsotg->dev, "## urb->hcpriv is NULL ##\n");
goto out;
}
rc = dwc2_hcd_urb_dequeue(hsotg, urb->hcpriv); // Use urb->hcpriv
...
out:
spin_unlock_irqrestore(&hsotg->lock, flags);
When _dwc2_hcd_urb_enqueue() and _dwc2_hcd_urb_dequeue() are
concurrently executed, the NULL check of "urb->hcpriv" can be executed
before "urb->hcpriv = NULL". After urb->hcpriv is NULL, it can be used
in the function call to dwc2_hcd_urb_dequeue(), which can cause a NULL
pointer dereference.
This possible bug is found by an experimental static analysis tool
developed by myself. This tool analyzes the locking APIs to extract
function pairs that can be concurrently executed, and then analyzes the
instructions in the paired functions to identify possible concurrency
bugs including data races and atomicity violations. The above possible
bug is reported, when my tool analyzes the source code of Linux 6.5.
To fix this possible bug, "urb->hcpriv = NULL" should be executed with
holding the lock "hsotg->lock". After using this patch, my tool never
reports the possible bug, with the kernelconfiguration allyesconfig for
x86_64. Because I have no associated hardware, I cannot test the patch
in runtime testing, and just verify it according to the code logic.
Fixes: 33ad261aa62b ("usb: dwc2: host: spinlock urb_enqueue")
Signed-off-by: Jia-Ju Bai <baijiaju(a)buaa.edu.cn>
Link: https://lore.kernel.org/r/20230926024404.832096-1-baijiaju@buaa.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: dinglongwei <dinglongwei1(a)huawei.com>
---
drivers/usb/dwc2/hcd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 2fe0b953921f..8b8c113b7267 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4844,8 +4844,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
if (qh_allocated && qh->channel && qh->channel->qh == qh)
qh->channel->qh = NULL;
fail2:
- spin_unlock_irqrestore(&hsotg->lock, flags);
urb->hcpriv = NULL;
+ spin_unlock_irqrestore(&hsotg->lock, flags);
kfree(qtd);
qtd = NULL;
fail1:
--
2.17.1
From: Maciej Żenczykowski <maze(a)google.com>
stable inclusion
from stable-v4.19.195
commit 45f9a2fe737dc0a5df270787f2231aee8985cd59
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9R49O
CVE: CVE-2021-47267
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 032e288097a553db5653af552dd8035cd2a0ba96 upstream.
usb_assign_descriptors() is called with 5 parameters,
the last 4 of which are the usb_descriptor_header for:
full-speed (USB1.1 - 12Mbps [including USB1.0 low-speed @ 1.5Mbps),
high-speed (USB2.0 - 480Mbps),
super-speed (USB3.0 - 5Gbps),
super-speed-plus (USB3.1 - 10Gbps).
The differences between full/high/super-speed descriptors are usually
substantial (due to changes in the maximum usb block size from 64 to 512
to 1024 bytes and other differences in the specs), while the difference
between 5 and 10Gbps descriptors may be as little as nothing
(in many cases the same tuning is simply good enough).
However if a gadget driver calls usb_assign_descriptors() with
a NULL descriptor for super-speed-plus and is then used on a max 10gbps
configuration, the kernel will crash with a null pointer dereference,
when a 10gbps capable device port + cable + host port combination shows up.
(This wouldn't happen if the gadget max-speed was set to 5gbps, but
it of course defaults to the maximum, and there's no real reason to
artificially limit it)
The fix is to simply use the 5gbps descriptor as the 10gbps descriptor,
if a 10gbps descriptor wasn't provided.
Obviously this won't fix the problem if the 5gbps descriptor is also
NULL, but such cases can't be so trivially solved (and any such gadgets
are unlikely to be used with USB3 ports any way).
Cc: Felipe Balbi <balbi(a)kernel.org>
Cc: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Maciej Żenczykowski <maze(a)google.com>
Cc: stable <stable(a)vger.kernel.org>
Link: https://lore.kernel.org/r/20210609024459.1126080-1-zenczykowski@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Xiang Yang <xiangyang3(a)huawei.com>
---
drivers/usb/gadget/config.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 2d115353424c..7275b58ce8cc 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -164,6 +164,14 @@ int usb_assign_descriptors(struct usb_function *f,
{
struct usb_gadget *g = f->config->cdev->gadget;
+ /* super-speed-plus descriptor falls back to super-speed one,
+ * if such a descriptor was provided, thus avoiding a NULL
+ * pointer dereference if a 5gbps capable gadget is used with
+ * a 10gbps capable config (device port + cable + host port)
+ */
+ if (!ssp)
+ ssp = ss;
+
if (fs) {
f->fs_descriptors = usb_copy_descriptors(fs);
if (!f->fs_descriptors)
--
2.34.1