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
From: GUO Zihua <guozihua(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9V12H
CVE: NA
--------------------------------
IMA detect the backing inode changes through i_version of the backing inode
would introduce a performance degrade, so introduce a config to allow
users to bypass the i_version detection or not.
Signed-off-by: GUO Zihua <guozihua(a)huawei.com>
Signed-off-by: Xiang Yang <xiangyang3(a)huawei.com>
---
arch/arm64/configs/openeuler_defconfig | 1 +
arch/x86/configs/openeuler_defconfig | 1 +
security/integrity/ima/Kconfig | 8 ++++++++
security/integrity/ima/ima_main.c | 6 ++++++
4 files changed, 16 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index 4a368f3a5964..ab1db78f049a 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -7364,6 +7364,7 @@ CONFIG_IMA_STANDARD_DIGEST_DB_SIZE=y
# CONFIG_IMA_CUSTOM_DIGEST_DB_SIZE is not set
CONFIG_IMA_DIGEST_DB_MEGABYTES=16
CONFIG_IMA_PARSER_BINARY_PATH="/usr/bin/upload_digest_lists"
+# CONFIG_IMA_OVERLAYFS_DETECTION_BYPASS is not set
CONFIG_EVM=y
# CONFIG_EVM_DEFAULT_HASH_SHA1 is not set
CONFIG_EVM_DEFAULT_HASH_SHA256=y
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 38c191ea24be..0c6fc6018c2c 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -8517,6 +8517,7 @@ CONFIG_IMA_STANDARD_DIGEST_DB_SIZE=y
# CONFIG_IMA_CUSTOM_DIGEST_DB_SIZE is not set
CONFIG_IMA_DIGEST_DB_MEGABYTES=16
CONFIG_IMA_PARSER_BINARY_PATH="/usr/bin/upload_digest_lists"
+# CONFIG_IMA_OVERLAYFS_DETECTION_BYPASS is not set
CONFIG_EVM=y
# CONFIG_EVM_DEFAULT_HASH_SHA1 is not set
CONFIG_EVM_DEFAULT_HASH_SHA256=y
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 46cb469e06ab..9d920d3ff4f0 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -368,4 +368,12 @@ config IMA_PARSER_BINARY_PATH
help
This option defines the path of the parser binary.
+config IMA_OVERLAYFS_DETECTION_BYPASS
+ bool "Bypass overlayfs backing inode change detection"
+ default n
+ help
+ This option enables user to bypass the overlayfs backing inode
+ change detection, while the detection may causes performance
+ regression. With this config enabled, IMA will not detect inode
+ change through i_version of the backing inode. If unsure, say N.
endif
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index d29dc604e1d3..9b251ecfa7c2 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -282,7 +282,11 @@ static int process_measurement(struct file *file, const struct cred *cred,
u32 secid, char *buf, loff_t size, int mask,
enum ima_hooks func)
{
+#ifndef CONFIG_IMA_OVERLAYFS_DETECTION_BYPASS
struct inode *backing_inode, *inode = file_inode(file);
+#else
+ struct inode *inode = file_inode(file);
+#endif
struct integrity_iint_cache *iint = NULL;
struct ima_template_desc *template_desc = NULL;
char *pathbuf = NULL;
@@ -362,6 +366,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
iint->measured_pcrs = 0;
}
+#ifndef CONFIG_IMA_OVERLAYFS_DETECTION_BYPASS
/* Detect and re-evaluate changes made to the backing file. */
backing_inode = d_real_inode(file_dentry(file));
if (backing_inode != inode &&
@@ -374,6 +379,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
iint->measured_pcrs = 0;
}
}
+#endif
/* Determine if already appraised/measured based on bitmask
* (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
--
2.34.1
From: Johannes Berg <johannes.berg(a)intel.com>
mainline inclusion
from mainline-v6.9-rc1
commit 9ad7974856926129f190ffbe3beea78460b3b7cc
category: bugfix
bugzilla: 190054, https://gitee.com/src-openeuler/kernel/issues/I9QGJD
CVE: CVE-2024-35937
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
If it looks like there's another subframe in the A-MSDU
but the header isn't fully there, we can end up reading
data out of bounds, only to discard later. Make this a
bit more careful and check if the subframe header can
even be present.
Reported-by: syzbot+d050d437fe47d479d210(a)syzkaller.appspotmail.com
Link: https://msgid.link/20240226203405.a731e2c95e38.I82ce7d8c0cc8970ce29d0a39fdc…
Signed-off-by: Johannes Berg <johannes.berg(a)intel.com>
Conflicts:
net/wireless/util.c
[ieee80211_is_valid_amsdu() isnt implemented in the
current version for commit 6e4c0d0460bd not merged.
commit 9f718554e7ea and 986e43b19ae9 wasnt merged,
which lead to context conflicts]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/wireless/util.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4b32e85c2d9a..5177fd63b1b8 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -751,24 +751,27 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
struct sk_buff *frame = NULL;
u16 ethertype;
u8 *payload;
- int offset = 0, remaining;
+ int offset = 0;
struct ethhdr eth;
bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
bool reuse_skb = false;
bool last = false;
while (!last) {
+ int remaining = skb->len - offset;
unsigned int subframe_len;
int len;
u8 padding;
+ if (sizeof(eth) > remaining)
+ goto purge;
+
skb_copy_bits(skb, offset, ð, sizeof(eth));
len = ntohs(eth.h_proto);
subframe_len = sizeof(struct ethhdr) + len;
padding = (4 - subframe_len) & 0x3;
/* the last MSDU has no padding */
- remaining = skb->len - offset;
if (subframe_len > remaining)
goto purge;
/* mitigate A-MSDU aggregation injection attacks */
--
2.25.1
From: Johannes Berg <johannes.berg(a)intel.com>
mainline inclusion
from mainline-v6.9-rc1
commit 9ad7974856926129f190ffbe3beea78460b3b7cc
category: bugfix
bugzilla: 190054, https://gitee.com/src-openeuler/kernel/issues/I9QGJD
CVE: CVE-2024-35937
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
If it looks like there's another subframe in the A-MSDU
but the header isn't fully there, we can end up reading
data out of bounds, only to discard later. Make this a
bit more careful and check if the subframe header can
even be present.
Reported-by: syzbot+d050d437fe47d479d210(a)syzkaller.appspotmail.com
Link: https://msgid.link/20240226203405.a731e2c95e38.I82ce7d8c0cc8970ce29d0a39fdc…
Signed-off-by: Johannes Berg <johannes.berg(a)intel.com>
Conflicts:
net/wireless/util.c
[ieee80211_is_valid_amsdu() isnt implemented in the
current version for commit 6e4c0d0460bd not merged.
commit 9f718554e7ea and 986e43b19ae9 wasnt merged,
which lead to context conflicts]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/wireless/util.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4b32e85c2d9a..5177fd63b1b8 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -751,24 +751,27 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
struct sk_buff *frame = NULL;
u16 ethertype;
u8 *payload;
- int offset = 0, remaining;
+ int offset = 0;
struct ethhdr eth;
bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
bool reuse_skb = false;
bool last = false;
while (!last) {
+ int remaining = skb->len - offset;
unsigned int subframe_len;
int len;
u8 padding;
+ if (sizeof(eth) > remaining)
+ goto purge;
+
skb_copy_bits(skb, offset, ð, sizeof(eth));
len = ntohs(eth.h_proto);
subframe_len = sizeof(struct ethhdr) + len;
padding = (4 - subframe_len) & 0x3;
/* the last MSDU has no padding */
- remaining = skb->len - offset;
if (subframe_len > remaining)
goto purge;
/* mitigate A-MSDU aggregation injection attacks */
--
2.25.1
From: Johannes Berg <johannes.berg(a)intel.com>
mainline inclusion
from mainline-v6.9-rc1
commit 9ad7974856926129f190ffbe3beea78460b3b7cc
category: bugfix
bugzilla: 190054, https://gitee.com/src-openeuler/kernel/issues/I9QGJD
CVE: CVE-2024-35937
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
If it looks like there's another subframe in the A-MSDU
but the header isn't fully there, we can end up reading
data out of bounds, only to discard later. Make this a
bit more careful and check if the subframe header can
even be present.
Reported-by: syzbot+d050d437fe47d479d210(a)syzkaller.appspotmail.com
Link: https://msgid.link/20240226203405.a731e2c95e38.I82ce7d8c0cc8970ce29d0a39fdc…
Signed-off-by: Johannes Berg <johannes.berg(a)intel.com>
Conflicts:
net/wireless/util.c
[ieee80211_is_valid_amsdu() isnt implemented in the
current version for commit 6e4c0d0460bd not merged.
commit 9f718554e7ea and 986e43b19ae9 wasnt merged,
which lead to context conflicts]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/wireless/util.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5fd7dc3ec5b0..b39ee17dbead 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -632,24 +632,27 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
struct sk_buff *frame = NULL;
u16 ethertype;
u8 *payload;
- int offset = 0, remaining;
+ int offset = 0;
struct ethhdr eth;
bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
bool reuse_skb = false;
bool last = false;
while (!last) {
+ int remaining = skb->len - offset;
unsigned int subframe_len;
int len;
u8 padding;
+ if (sizeof(eth) > remaining)
+ goto purge;
+
skb_copy_bits(skb, offset, ð, sizeof(eth));
len = ntohs(eth.h_proto);
subframe_len = sizeof(struct ethhdr) + len;
padding = (4 - subframe_len) & 0x3;
/* the last MSDU has no padding */
- remaining = skb->len - offset;
if (subframe_len > remaining)
goto purge;
/* mitigate A-MSDU aggregation injection attacks */
--
2.25.1