From: Xiang Chen chenxiang66@hisilicon.com
mainline inclusion from mainline-v5.19-rc7 commit 1e82e4627a795 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5M9GC CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------------------------------------
Currently if a phy reset or enable phy is issued via sysfs when controller is suspended, those operations will be ignored as SAS_HA_REGISTERED is cleared. If RPM is enabled then we may aggressively suspend automatically. In this case it may be difficult to enable or reset a phy via sysfs, so resume the host in these scenarios.
Link: https://lore.kernel.org/r/1657823002-139010-6-git-send-email-john.garry@huaw... Signed-off-by: Xiang Chen chenxiang66@hisilicon.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: xiabing xiabing12@h-partners.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/scsi/libsas/sas_init.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index f1989a98f511..58ffcecf1a2f 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -528,6 +528,7 @@ static int queue_phy_reset(struct sas_phy *phy, int hard_reset) if (!d) return -ENOMEM;
+ pm_runtime_get_sync(ha->dev); /* libsas workqueue coordinates ata-eh reset with discovery */ mutex_lock(&d->event_lock); d->reset_result = 0; @@ -541,6 +542,7 @@ static int queue_phy_reset(struct sas_phy *phy, int hard_reset) if (rc == 0) rc = d->reset_result; mutex_unlock(&d->event_lock); + pm_runtime_put_sync(ha->dev);
return rc; } @@ -555,6 +557,7 @@ static int queue_phy_enable(struct sas_phy *phy, int enable) if (!d) return -ENOMEM;
+ pm_runtime_get_sync(ha->dev); /* libsas workqueue coordinates ata-eh reset with discovery */ mutex_lock(&d->event_lock); d->enable_result = 0; @@ -568,6 +571,7 @@ static int queue_phy_enable(struct sas_phy *phy, int enable) if (rc == 0) rc = d->enable_result; mutex_unlock(&d->event_lock); + pm_runtime_put_sync(ha->dev);
return rc; }
From: Luo Meng luomeng12@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5WBQA CVE: NA
--------------------------------
This reverts commit 1f9fa07bfd68f9bcf65e80d59606e71878c74c64.
Commit 2fe0e281f7ad witch merged by LTS (cifs: fix double free race when mount fails in cifs_get_root()) fixes a double free. However, the previous patch d17abdf75665 is not merged. There is no such issue on 5.10 because it will return after cifs_cleanup_volume_info().
Since merge this patch, cifs_cleanup_volume_info() is skipped, leading to a memory leak.
Signed-off-by: Luo Meng luomeng12@huawei.com Reviewed-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- fs/cifs/cifsfs.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index bc957e6ca48b..6e1e7e44706c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -864,7 +864,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
out_super: deactivate_locked_super(sb); - return root; out: cifs_cleanup_volume_info(volume_info); return root;
On 11/7/22 8:51 PM, Zheng Zengkai wrote:
From: Luo Meng luomeng12@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5WBQA CVE: NA
This reverts commit 1f9fa07bfd68f9bcf65e80d59606e71878c74c64.
Commit 2fe0e281f7ad witch merged by LTS (cifs: fix double free race when mount fails in cifs_get_root()) fixes a double free. However, the previous patch d17abdf75665 is not merged. There is no such issue on 5.10 because it will return after cifs_cleanup_volume_info().
Since merge this patch, cifs_cleanup_volume_info() is skipped, leading to a memory leak.
Signed-off-by: Luo Meng luomeng12@huawei.com Reviewed-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com
fs/cifs/cifsfs.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index bc957e6ca48b..6e1e7e44706c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -864,7 +864,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
out_super: deactivate_locked_super(sb);
- return root; out: cifs_cleanup_volume_info(volume_info); return root;
I'd suggest to send it to 5.10 stable too.
Thanks, Guoqing
在 2022/11/10 12:17, Guoqing Jiang 写道:
On 11/7/22 8:51 PM, Zheng Zengkai wrote:
From: Luo Meng luomeng12@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5WBQA CVE: NA
This reverts commit 1f9fa07bfd68f9bcf65e80d59606e71878c74c64.
Commit 2fe0e281f7ad witch merged by LTS (cifs: fix double free race when mount fails in cifs_get_root()) fixes a double free. However, the previous patch d17abdf75665 is not merged. There is no such issue on 5.10 because it will return after cifs_cleanup_volume_info().
Since merge this patch, cifs_cleanup_volume_info() is skipped, leading to a memory leak.
Signed-off-by: Luo Meng luomeng12@huawei.com Reviewed-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com
fs/cifs/cifsfs.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index bc957e6ca48b..6e1e7e44706c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -864,7 +864,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, out_super: deactivate_locked_super(sb); - return root; out: cifs_cleanup_volume_info(volume_info); return root;
I'd suggest to send it to 5.10 stable too.
Thanks, Guoqing
Yes, I have backported this patch to openEuler-22.0-LTS branch,
thanks!
Kernel mailing list -- kernel@openeuler.org To unsubscribe send an email to kernel-leave@openeuler.org
From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.11-rc1 commit ee4bf648635055d2b76afadaf34236c8b2d852a7 category: bugfix bugzilla: 187706,https://gitee.com/openeuler/kernel/issues/I5XEBX CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------
Block driver have no business setting the file system concept of a block size.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Jens Axboe axboe@kernel.dk
conflicts: drivers/block/nbd.c
Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/block/nbd.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 105ae87388bc..ea205736088c 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -301,7 +301,7 @@ static void nbd_size_clear(struct nbd_device *nbd) } }
-static void nbd_size_update(struct nbd_device *nbd, bool start) +static void nbd_size_update(struct nbd_device *nbd) { struct nbd_config *config = nbd->config; struct block_device *bdev = bdget_disk(nbd->disk, 0); @@ -316,11 +316,9 @@ static void nbd_size_update(struct nbd_device *nbd, bool start) blk_queue_physical_block_size(nbd->disk->queue, config->blksize); set_capacity(nbd->disk, nr_sectors); if (bdev) { - if (bdev->bd_disk) { + if (bdev->bd_disk) bd_set_nr_sectors(bdev, nr_sectors); - if (start) - set_blocksize(bdev, config->blksize); - } else + else set_bit(GD_NEED_PART_SCAN, &nbd->disk->state); bdput(bdev); } @@ -334,7 +332,7 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize, config->blksize = blocksize; config->bytesize = blocksize * nr_blocks; if (nbd->pid) - nbd_size_update(nbd, false); + nbd_size_update(nbd); }
static void nbd_complete_rq(struct request *req) @@ -1393,7 +1391,7 @@ static int nbd_start_device(struct nbd_device *nbd) args->index = i; queue_work(nbd->recv_workq, &args->work); } - nbd_size_update(nbd, true); + nbd_size_update(nbd); return error; }
From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.11-rc1 commit 92f93c3a1bf9dc73181dc6566497d16b690cb576 category: bugfix bugzilla: 187706,,https://gitee.com/openeuler/kernel/issues/I5XEBX CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------
nbd_size_update is about to acquire a few more callers, so lift the check into the function.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Jens Axboe axboe@kernel.dk
Conflicts: drivers/block/nbd.c [0c98057be9ef ("nbd: Fix use-after-free in pid_show") include first]
Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/block/nbd.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index ea205736088c..911dea4f7866 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -304,8 +304,11 @@ static void nbd_size_clear(struct nbd_device *nbd) static void nbd_size_update(struct nbd_device *nbd) { struct nbd_config *config = nbd->config; - struct block_device *bdev = bdget_disk(nbd->disk, 0); sector_t nr_sectors = config->bytesize >> 9; + struct block_device *bdev; + + if (!nbd->pid) + return;
if (config->flags & NBD_FLAG_SEND_TRIM) { nbd->disk->queue->limits.discard_granularity = config->blksize; @@ -314,7 +317,9 @@ static void nbd_size_update(struct nbd_device *nbd) } blk_queue_logical_block_size(nbd->disk->queue, config->blksize); blk_queue_physical_block_size(nbd->disk->queue, config->blksize); + set_capacity(nbd->disk, nr_sectors); + bdev = bdget_disk(nbd->disk, 0); if (bdev) { if (bdev->bd_disk) bd_set_nr_sectors(bdev, nr_sectors); @@ -331,8 +336,7 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize, struct nbd_config *config = nbd->config; config->blksize = blocksize; config->bytesize = blocksize * nr_blocks; - if (nbd->pid) - nbd_size_update(nbd); + nbd_size_update(nbd); }
static void nbd_complete_rq(struct request *req)
From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.11-rc1 commit 2dc691cc4ac259f8b5bb0bd8670645af894d30eb category: bugfix bugzilla: 187706,https://gitee.com/openeuler/kernel/issues/I5XEBX CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------
Merge nbd_size_set and nbd_size_update into a single function that also updates the nbd_config fields. This new function takes the device size in bytes as the first argument, and the blocksize as the second argument, simplifying the calculations required in most callers.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Jens Axboe axboe@kernel.dk
Conflicts: drivers/block/nbd.c
Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/block/nbd.c | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 911dea4f7866..ebcdb6025be3 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -301,28 +301,30 @@ static void nbd_size_clear(struct nbd_device *nbd) } }
-static void nbd_size_update(struct nbd_device *nbd) +static void nbd_set_size(struct nbd_device *nbd, loff_t bytesize, + loff_t blksize) { - struct nbd_config *config = nbd->config; - sector_t nr_sectors = config->bytesize >> 9; struct block_device *bdev;
+ nbd->config->bytesize = bytesize; + nbd->config->blksize = blksize; + if (!nbd->pid) return;
- if (config->flags & NBD_FLAG_SEND_TRIM) { - nbd->disk->queue->limits.discard_granularity = config->blksize; - nbd->disk->queue->limits.discard_alignment = config->blksize; + if (nbd->config->flags & NBD_FLAG_SEND_TRIM) { + nbd->disk->queue->limits.discard_granularity = blksize; + nbd->disk->queue->limits.discard_alignment = blksize; blk_queue_max_discard_sectors(nbd->disk->queue, UINT_MAX); } - blk_queue_logical_block_size(nbd->disk->queue, config->blksize); - blk_queue_physical_block_size(nbd->disk->queue, config->blksize); + blk_queue_logical_block_size(nbd->disk->queue, blksize); + blk_queue_physical_block_size(nbd->disk->queue, blksize);
- set_capacity(nbd->disk, nr_sectors); + set_capacity(nbd->disk, bytesize >> 9); bdev = bdget_disk(nbd->disk, 0); if (bdev) { if (bdev->bd_disk) - bd_set_nr_sectors(bdev, nr_sectors); + bd_set_nr_sectors(bdev, bytesize >> 9); else set_bit(GD_NEED_PART_SCAN, &nbd->disk->state); bdput(bdev); @@ -330,15 +332,6 @@ static void nbd_size_update(struct nbd_device *nbd) kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE); }
-static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize, - loff_t nr_blocks) -{ - struct nbd_config *config = nbd->config; - config->blksize = blocksize; - config->bytesize = blocksize * nr_blocks; - nbd_size_update(nbd); -} - static void nbd_complete_rq(struct request *req) { struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req); @@ -1395,7 +1388,7 @@ static int nbd_start_device(struct nbd_device *nbd) args->index = i; queue_work(nbd->recv_workq, &args->work); } - nbd_size_update(nbd); + nbd_set_size(nbd, config->bytesize, config->blksize); return error; }
@@ -1475,17 +1468,15 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, arg = NBD_DEF_BLKSIZE; if (!nbd_is_valid_blksize(arg)) return -EINVAL; - nbd_size_set(nbd, arg, - div_s64(config->bytesize, arg)); + nbd_set_size(nbd, config->bytesize, arg); return 0; case NBD_SET_SIZE: - nbd_size_set(nbd, config->blksize, - div_s64(arg, config->blksize)); + nbd_set_size(nbd, arg, config->blksize); return 0; case NBD_SET_SIZE_BLOCKS: if (check_mul_overflow((loff_t)arg, config->blksize, &bytesize)) return -EINVAL; - nbd_size_set(nbd, config->blksize, arg); + nbd_set_size(nbd, bytesize, config->blksize); return 0; case NBD_SET_TIMEOUT: nbd_set_cmd_timeout(nbd, arg); @@ -1922,7 +1913,7 @@ static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd) }
if (bytes != config->bytesize || bsize != config->blksize) - nbd_size_set(nbd, bsize, div64_u64(bytes, bsize)); + nbd_set_size(nbd, bytes, bsize); return 0; }
From: Jie Zhan zhanjie9@hisilicon.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5GNIE
------------------------------------------------------------------------
Since commit 4615fbc3788d ("genirq/irqdomain: Don't try to free an interrupt that has no mapping"), we have found failures when re-inserting some specific drivers:
[root@localhost ~]# rmmod hisi_sas_v3_hw [root@localhost ~]# modprobe hisi_sas_v3_hw [ 1295.622525] hisi_sas_v3_hw: probe of 0000:30:04.0 failed with error -2
A relevant discussion can be found at: https://lore.kernel.org/lkml/3d3d0155e66429968cb4f6b4feeae4b3@kernel.org/
This is because IRQs from a low-level domain are not freed together, leaving some leaked. Thus, the next driver insertion fails to allocate the same number of IRQs.
Free a contiguous group of IRQs in one go to fix this issue.
Fixes: 4615fbc3788d ("genirq/irqdomain: Don't try to free an interrupt that has no mapping") Signed-off-by: Jie Zhan zhanjie9@hisilicon.com Reviewed-by: Liao Chang liaochang1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- kernel/irq/irqdomain.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index c6b419db68ef..ed2fb45e8cae 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1374,13 +1374,24 @@ static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain, unsigned int nr_irqs) { unsigned int i; + int n;
if (!domain->ops->free) return;
for (i = 0; i < nr_irqs; i++) { - if (irq_domain_get_irq_data(domain, irq_base + i)) - domain->ops->free(domain, irq_base + i, 1); + /* Find the largest possible span of IRQs to free in one go */ + for (n = 0; + ((i + n) < nr_irqs) && + (irq_domain_get_irq_data(domain, irq_base + i + n)); + n++) + ; + + if (!n) + continue; + + domain->ops->free(domain, irq_base + i, n); + i += n; } }
From: Ziyang Xuan william.xuanziyang@huawei.com
maillist inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5Z86E CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=36...
--------------------------------
Recently, we got two syzkaller problems because of oversize packet when napi frags enabled.
One of the problems is because the first seg size of the iov_iter from user space is very big, it is 2147479538 which is bigger than the threshold value for bail out early in __alloc_pages(). And skb->pfmemalloc is true, __kmalloc_reserve() would use pfmemalloc reserves without __GFP_NOWARN flag. Thus we got a warning as following:
======================================================== WARNING: CPU: 1 PID: 17965 at mm/page_alloc.c:5295 __alloc_pages+0x1308/0x16c4 mm/page_alloc.c:5295 ... Call trace: __alloc_pages+0x1308/0x16c4 mm/page_alloc.c:5295 __alloc_pages_node include/linux/gfp.h:550 [inline] alloc_pages_node include/linux/gfp.h:564 [inline] kmalloc_large_node+0x94/0x350 mm/slub.c:4038 __kmalloc_node_track_caller+0x620/0x8e4 mm/slub.c:4545 __kmalloc_reserve.constprop.0+0x1e4/0x2b0 net/core/skbuff.c:151 pskb_expand_head+0x130/0x8b0 net/core/skbuff.c:1654 __skb_grow include/linux/skbuff.h:2779 [inline] tun_napi_alloc_frags+0x144/0x610 drivers/net/tun.c:1477 tun_get_user+0x31c/0x2010 drivers/net/tun.c:1835 tun_chr_write_iter+0x98/0x100 drivers/net/tun.c:2036
The other problem is because odd IPv6 packets without NEXTHDR_NONE extension header and have big packet length, it is 2127925 which is bigger than ETH_MAX_MTU(65535). After ipv6_gso_pull_exthdrs() in ipv6_gro_receive(), network_header offset and transport_header offset are all bigger than U16_MAX. That would trigger skb->network_header and skb->transport_header overflow error, because they are all '__u16' type. Eventually, it would affect the value for __skb_push(skb, value), and make it be a big value. After __skb_push() in ipv6_gro_receive(), skb->data would less than skb->head, an out of bounds memory bug occurred. That would trigger the problem as following:
================================================================== BUG: KASAN: use-after-free in eth_type_trans+0x100/0x260 ... Call trace: dump_backtrace+0xd8/0x130 show_stack+0x1c/0x50 dump_stack_lvl+0x64/0x7c print_address_description.constprop.0+0xbc/0x2e8 print_report+0x100/0x1e4 kasan_report+0x80/0x120 __asan_load8+0x78/0xa0 eth_type_trans+0x100/0x260 napi_gro_frags+0x164/0x550 tun_get_user+0xda4/0x1270 tun_chr_write_iter+0x74/0x130 do_iter_readv_writev+0x130/0x1ec do_iter_write+0xbc/0x1e0 vfs_writev+0x13c/0x26c
To fix the problems, restrict the packet size less than (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN) which has considered reserved skb space in napi_alloc_skb() because transport_header is an offset from skb->head. Add len check in tun_napi_alloc_frags() simply.
Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver") Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/20221029094101.1653855-1-william.xuanziyang@huawei... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/net/tun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a3b187ca43f8..f8f15f2f7cc8 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1475,7 +1475,8 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, int err; int i;
- if (it->nr_segs > MAX_SKB_FRAGS + 1) + if (it->nr_segs > MAX_SKB_FRAGS + 1 || + len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN)) return ERR_PTR(-EMSGSIZE);
local_bh_disable();
From: GUO Zihua guozihua@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5Z7MD CVE: NA
--------------------------------
Return of crypto_alloc_shash would be either a valid pointer or an error pointer. We should check the result with IS_ERR.
Signed-off-by: GUO Zihua guozihua@huawei.com Reviewed-by: Xiu Jianfeng xiujianfeng@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- crypto/asymmetric_keys/pgp_public_key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/asymmetric_keys/pgp_public_key.c b/crypto/asymmetric_keys/pgp_public_key.c index 928029a13435..e49bb79736da 100644 --- a/crypto/asymmetric_keys/pgp_public_key.c +++ b/crypto/asymmetric_keys/pgp_public_key.c @@ -131,7 +131,7 @@ static int pgp_generate_fingerprint(struct pgp_key_data_parse_context *ctx, ret = -ENOMEM; tfm = crypto_alloc_shash(pgp->version < PGP_KEY_VERSION_4 ? "md5" : "sha1", 0, 0); - if (!tfm) + if (IS_ERR(tfm)) goto cleanup;
digest = kmalloc(sizeof(*digest) + crypto_shash_descsize(tfm),
From: Ye Bin yebin10@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5ZHOZ CVE: NA
--------------------------------
There's issue as follows when do test with memory fault injection: [localhost]# fsck.ext4 -a image image: clean, 45595/655360 files, 466841/2621440 blocks [localhost]# fsck.ext4 -fn image Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information Block bitmap differences: -(1457230--1457256) Fix? no
image: ********** WARNING: Filesystem still has errors **********
image: 45595/655360 files (12.4% non-contiguous), 466841/2621440 blocks
Inject context: ----------------------------------------------------------- Inject function:kmem_cache_alloc (pid:177858) (return: 0) Calltrace Context: mem_cache_allock+0x73/0xcc ext4_mb_new_blocks+0x32e/0x540 [ext4] ext4_new_meta_blocks+0xc4/0x110 [ext4] ext4_ext_grow_indepth+0x68/0x250 [ext4] ext4_ext_create_new_leaf+0xc5/0x120 [ext4] ext4_ext_insert_extent+0x1bf/0x670 [ext4] ext4_split_extent_at+0x212/0x530 [ext4] ext4_split_extent+0x13a/0x1a0 [ext4] ext4_ext_handle_unwritten_extents+0x13d/0x240 [ext4] ext4_ext_map_blocks+0x459/0x8f0 [ext4] ext4_map_blocks+0x18e/0x5a0 [ext4] ext4_iomap_alloc+0xb0/0x1b0 [ext4] ext4_iomap_begin+0xb0/0x130 [ext4] iomap_apply+0x95/0x2e0 __iomap_dio_rw+0x1cc/0x4b0 iomap_dio_rw+0xe/0x40 ext4_dio_write_iter+0x1a9/0x390 [ext4] new_sync_write+0x113/0x1b0 vfs_write+0x1b7/0x250 ksys_write+0x5f/0xe0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x61/0xc6
Compare extent change in journal: Start: ee_block ee_len ee_start 75 32798 1457227 -> unwritten len=30 308 12 434489 355 5 442492 => ee_block ee_len ee_start 11 2 951584 74 32769 951647 -> unwritten len=1 75 32771 1457227 -> unwritten len=3 211 15 960906 308 12 434489 355 5 442492
Acctually, above issue can repaired by 'fsck -fa'. But file system is 'clean', 'fsck' will not do deep repair. Obviously, final lost 27 blocks. Above issue may happens as follows: ext4_split_extent_at ... err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags); -> return -ENOMEM if (err != -ENOSPC && err != -EDQUOT) goto out; -> goto 'out' will not fix extent length, will ... fix_extent_len: ex->ee_len = orig_ex.ee_len; /* * Ignore ext4_ext_dirty return value since we are already in error path * and err is a non-zero error code. */ ext4_ext_dirty(handle, inode, path + path->p_depth); return err; out: ext4_ext_show_leaf(inode, path); return err; If 'ext4_ext_insert_extent' return '-ENOMEM' which will not fix 'ex->ee_len' by old length. 'ext4_ext_insert_extent' will trigger extent tree merge, fix like 'ex->ee_len = orig_ex.ee_len' may lead to new issues. To solve above issue, record error messages when 'ext4_ext_insert_extent' return 'err' not equal '(-ENOSPC && -EDQUOT)'. If filesysten is mounted with 'errors=continue' as filesystem is not clean 'fsck' will repair issue. If filesystem is mounted with 'errors=remount-ro' filesystem will be remounted by read-only.
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- fs/ext4/extents.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 1a4ac8aa1e96..6202bd153934 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3253,8 +3253,13 @@ static int ext4_split_extent_at(handle_t *handle, ext4_ext_mark_unwritten(ex2);
err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags); - if (err != -ENOSPC && err != -EDQUOT) + if (err != -ENOSPC && err != -EDQUOT) { + if (err) + EXT4_ERROR_INODE_ERR(inode, -err, + "insert extent failed block = %d len = %d", + ex2->ee_block, ex2->ee_len); goto out; + }
if (EXT4_EXT_MAY_ZEROOUT & split_flag) { if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) {
From: Ye Bin yebin10@huawei.com
mainline inclusion from mainline-v6.1-rc2 commit 60a9bb9048f9e95029df10a9bc346f6b066c593c category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5ZI04 CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h...
--------------------------------
Introduce 'blk_trace_{start,stop}' helper. No functional changed.
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20221019033602.752383-2-yebin@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk
conflicts: kernel/trace/blktrace.c
Signed-off-by: Ye Bin yebin@huaweicloud.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- kernel/trace/blktrace.c | 74 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 38 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index b3afd103b3aa..941553c3e0af 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -337,6 +337,37 @@ static void put_probe_ref(void) mutex_unlock(&blk_probe_mutex); }
+static int blk_trace_start(struct blk_trace *bt) +{ + if (bt->trace_state != Blktrace_setup && + bt->trace_state != Blktrace_stopped) + return -EINVAL; + + blktrace_seq++; + smp_mb(); + bt->trace_state = Blktrace_running; + spin_lock_irq(&running_trace_lock); + list_add(&bt->running_list, &running_trace_list); + spin_unlock_irq(&running_trace_lock); + trace_note_time(bt); + + return 0; +} + +static int blk_trace_stop(struct blk_trace *bt) +{ + if (bt->trace_state != Blktrace_running) + return -EINVAL; + + bt->trace_state = Blktrace_stopped; + spin_lock_irq(&running_trace_lock); + list_del_init(&bt->running_list); + spin_unlock_irq(&running_trace_lock); + relay_flush(bt->rchan); + + return 0; +} + static void blk_trace_cleanup(struct blk_trace *bt) { synchronize_rcu(); @@ -656,7 +687,6 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name,
static int __blk_trace_startstop(struct request_queue *q, int start) { - int ret; struct blk_trace *bt;
bt = rcu_dereference_protected(q->blk_trace, @@ -664,36 +694,10 @@ static int __blk_trace_startstop(struct request_queue *q, int start) if (bt == NULL) return -EINVAL;
- /* - * For starting a trace, we can transition from a setup or stopped - * trace. For stopping a trace, the state must be running - */ - ret = -EINVAL; - if (start) { - if (bt->trace_state == Blktrace_setup || - bt->trace_state == Blktrace_stopped) { - blktrace_seq++; - smp_mb(); - bt->trace_state = Blktrace_running; - spin_lock_irq(&running_trace_lock); - list_add(&bt->running_list, &running_trace_list); - spin_unlock_irq(&running_trace_lock); - - trace_note_time(bt); - ret = 0; - } - } else { - if (bt->trace_state == Blktrace_running) { - bt->trace_state = Blktrace_stopped; - spin_lock_irq(&running_trace_lock); - list_del_init(&bt->running_list); - spin_unlock_irq(&running_trace_lock); - relay_flush(bt->rchan); - ret = 0; - } - } - - return ret; + if (start) + return blk_trace_start(bt); + else + return blk_trace_stop(bt); }
int blk_trace_startstop(struct request_queue *q, int start) @@ -1671,13 +1675,7 @@ static int blk_trace_remove_queue(struct request_queue *q) if (bt == NULL) return -EINVAL;
- if (bt->trace_state == Blktrace_running) { - bt->trace_state = Blktrace_stopped; - spin_lock_irq(&running_trace_lock); - list_del_init(&bt->running_list); - spin_unlock_irq(&running_trace_lock); - relay_flush(bt->rchan); - } + blk_trace_stop(bt);
put_probe_ref(); synchronize_rcu();
From: Ye Bin yebin10@huawei.com
mainline inclusion from mainline-v6.1-rc2 commit dcd1a59c62dc49da75539213611156d6db50ab5d category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5ZI04 CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h...
--------------------------------
When test as follows: step1: ioctl(sda, BLKTRACESETUP, &arg) step2: ioctl(sda, BLKTRACESTART, NULL) step3: ioctl(sda, BLKTRACETEARDOWN, NULL) step4: ioctl(sda, BLKTRACESETUP, &arg) Got issue as follows: debugfs: File 'dropped' in directory 'sda' already present! debugfs: File 'msg' in directory 'sda' already present! debugfs: File 'trace0' in directory 'sda' already present!
And also find syzkaller report issue like "KASAN: use-after-free Read in relay_switch_subbuf" "https://syzkaller.appspot.com/bug?id=13849f0d9b1b818b087341691be6cc3ac6a6bfb..."
If remove block trace without stop(BLKTRACESTOP) block trace, '__blk_trace_remove' will just set 'q->blk_trace' with NULL. However, debugfs file isn't removed, so will report file already present when call BLKTRACESETUP. static int __blk_trace_remove(struct request_queue *q) { struct blk_trace *bt;
bt = rcu_replace_pointer(q->blk_trace, NULL, lockdep_is_held(&q->debugfs_mutex)); if (!bt) return -EINVAL;
if (bt->trace_state != Blktrace_running) blk_trace_cleanup(q, bt);
return 0; }
If do test as follows: step1: ioctl(sda, BLKTRACESETUP, &arg) step2: ioctl(sda, BLKTRACESTART, NULL) step3: ioctl(sda, BLKTRACETEARDOWN, NULL) step4: remove sda
There will remove debugfs directory which will remove recursively all file under directory.
blk_release_queue debugfs_remove_recursive(q->debugfs_dir)
So all files which created in 'do_blk_trace_setup' are removed, and 'dentry->d_inode' is NULL. But 'q->blk_trace' is still in 'running_trace_lock', 'trace_note_tsk' will traverse 'running_trace_lock' all nodes.
trace_note_tsk trace_note relay_reserve relay_switch_subbuf d_inode(buf->dentry)->i_size
To solve above issues, reference commit '5afedf670caf', call 'blk_trace_cleanup' unconditionally in '__blk_trace_remove' and first stop block trace in 'blk_trace_cleanup'.
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20221019033602.752383-3-yebin@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk
conflicts: kernel/trace/blktrace.c
Signed-off-by: Ye Bin yebin@huaweicloud.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- kernel/trace/blktrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 941553c3e0af..c49782bac8ad 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -370,6 +370,7 @@ static int blk_trace_stop(struct blk_trace *bt)
static void blk_trace_cleanup(struct blk_trace *bt) { + blk_trace_stop(bt); synchronize_rcu(); blk_trace_free(bt); put_probe_ref(); @@ -384,8 +385,7 @@ static int __blk_trace_remove(struct request_queue *q) if (!bt) return -EINVAL;
- if (bt->trace_state != Blktrace_running) - blk_trace_cleanup(bt); + blk_trace_cleanup(bt);
return 0; }
From: Ye Bin yebin10@huawei.com
mainline inclusion from mainline-v6.1-rc2 commit 2db96217e7e515071726ca4ec791742c4202a1b2 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5ZI04 CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h...
--------------------------------
As previous commit, 'blk_trace_cleanup' will stop block trace if block trace's state is 'Blktrace_running'. So remove unnessary stop block trace in 'blk_trace_shutdown'.
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20221019033602.752383-4-yebin@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk
conflicts: kernel/trace/blktrace.c
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- kernel/trace/blktrace.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index c49782bac8ad..ee8c21189423 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -775,10 +775,8 @@ void blk_trace_shutdown(struct request_queue *q) { mutex_lock(&q->debugfs_mutex); if (rcu_dereference_protected(q->blk_trace, - lockdep_is_held(&q->debugfs_mutex))) { - __blk_trace_startstop(q, 0); + lockdep_is_held(&q->debugfs_mutex))) __blk_trace_remove(q); - }
mutex_unlock(&q->debugfs_mutex); }