mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 53 participants
  • 18755 discussions
[PATCH openEuler-22.03-LTS-SP1] hugetlbfs: fix hugetlbfs_statfs() locking
by Yifan Qiao 11 Jun '24

11 Jun '24
From: Mina Almasry <almasrymina(a)google.com> mainline inclusion from mainline-v5.19-rc1 commit 4b25f030ae69ba710eff587cabb4c57cb7e7a8a1 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9SY02 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… ---------------------------------------------------------------------- After commit db71ef79b59b ("hugetlb: make free_huge_page irq safe"), the subpool lock should be locked with spin_lock_irq() and all call sites was modified as such, except for the ones in hugetlbfs_statfs(). Link: https://lkml.kernel.org/r/20220429202207.3045-1-almasrymina@google.com Fixes: db71ef79b59b ("hugetlb: make free_huge_page irq safe") Signed-off-by: Mina Almasry <almasrymina(a)google.com> Reviewed-by: Mike Kravetz <mike.kravetz(a)oracle.com> Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org> Signed-off-by: Yifan Qiao <qiaoyifan4(a)huawei.com> --- fs/hugetlbfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8274f096e89f..73a008dfe322 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1122,12 +1122,12 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) if (sbinfo->spool) { long free_pages; - spin_lock(&sbinfo->spool->lock); + spin_lock_irq(&sbinfo->spool->lock); buf->f_blocks = sbinfo->spool->max_hpages; free_pages = sbinfo->spool->max_hpages - sbinfo->spool->used_hpages; buf->f_bavail = buf->f_bfree = free_pages; - spin_unlock(&sbinfo->spool->lock); + spin_unlock_irq(&sbinfo->spool->lock); buf->f_files = sbinfo->max_inodes; buf->f_ffree = sbinfo->free_inodes; } -- 2.39.2
2 1
0 0
[PATCH OLK-5.10] hugetlbfs: fix hugetlbfs_statfs() locking
by Yifan Qiao 11 Jun '24

11 Jun '24
From: Mina Almasry <almasrymina(a)google.com> mainline inclusion from mainline-v5.19-rc1 commit 4b25f030ae69ba710eff587cabb4c57cb7e7a8a1 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9SY02 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… ---------------------------------------------------------------------- After commit db71ef79b59b ("hugetlb: make free_huge_page irq safe"), the subpool lock should be locked with spin_lock_irq() and all call sites was modified as such, except for the ones in hugetlbfs_statfs(). Link: https://lkml.kernel.org/r/20220429202207.3045-1-almasrymina@google.com Fixes: db71ef79b59b ("hugetlb: make free_huge_page irq safe") Signed-off-by: Mina Almasry <almasrymina(a)google.com> Reviewed-by: Mike Kravetz <mike.kravetz(a)oracle.com> Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org> Signed-off-by: Yifan Qiao <qiaoyifan4(a)huawei.com> --- fs/hugetlbfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 508c20ef9061..1203178914cc 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1133,12 +1133,12 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) if (sbinfo->spool) { long free_pages; - spin_lock(&sbinfo->spool->lock); + spin_lock_irq(&sbinfo->spool->lock); buf->f_blocks = sbinfo->spool->max_hpages; free_pages = sbinfo->spool->max_hpages - sbinfo->spool->used_hpages; buf->f_bavail = buf->f_bfree = free_pages; - spin_unlock(&sbinfo->spool->lock); + spin_unlock_irq(&sbinfo->spool->lock); buf->f_files = sbinfo->max_inodes; buf->f_ffree = sbinfo->free_inodes; } -- 2.39.2
2 1
0 0
[PATCH OLK-6.6] gpiolib: cdev: fix uninitialised kfifo
by Luo Gengkun 11 Jun '24

11 Jun '24
From: Kent Gibson <warthog618(a)gmail.com> mainline inclusion from mainline-v6.9 commit ee0166b637a5e376118e9659e5b4148080f1d27e category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9U7YV CVE: CVE-2024-36898 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- If a line is requested with debounce, and that results in debouncing in software, and the line is subsequently reconfigured to enable edge detection then the allocation of the kfifo to contain edge events is overlooked. This results in events being written to and read from an uninitialised kfifo. Read events are returned to userspace. Initialise the kfifo in the case where the software debounce is already active. Fixes: 65cff7046406 ("gpiolib: cdev: support setting debounce") Signed-off-by: Kent Gibson <warthog618(a)gmail.com> Link: https://lore.kernel.org/r/20240510065342.36191-1-warthog618@gmail.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski(a)linaro.org> Conflicts: drivers/gpio/gpiolib-cdev.c [fix context conflict] Signed-off-by: Luo Gengkun <luogengkun2(a)huawei.com> --- drivers/gpio/gpiolib-cdev.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 84125e55de10..29b671c92621 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1121,6 +1121,8 @@ static int edge_detector_update(struct line *line, struct gpio_v2_line_config *lc, unsigned int line_idx, u64 edflags) { + u64 eflags; + int ret; u64 active_edflags = READ_ONCE(line->edflags); unsigned int debounce_period_us = gpio_v2_line_config_debounce_period(lc, line_idx); @@ -1132,6 +1134,18 @@ static int edge_detector_update(struct line *line, /* sw debounced and still will be...*/ if (debounce_period_us && READ_ONCE(line->sw_debounced)) { WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us); + /* + * ensure event fifo is initialised if edge detection + * is now enabled. + */ + eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS; + if (eflags && !kfifo_initialized(&line->req->events)) { + ret = kfifo_alloc(&line->req->events, + line->req->event_buffer_size, + GFP_KERNEL); + if (ret) + return ret; + } return 0; } -- 2.34.1
2 1
0 0
[PATCH OLK-5.10] xfs: fix interval filtering in multi-step fsmap queries
by Zizhi Wo 11 Jun '24

11 Jun '24
From: "Darrick J. Wong" <djwong(a)kernel.org> mainline inclusion from mainline-v6.5-rc1 commit 63ef7a35912dd743cabd65d5bb95891625c0dd46 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IA470G Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- I noticed a bug in ranged GETFSMAP queries: EXT: DEV BLOCK-RANGE OWNER FILE-OFFSET AG AG-OFFSET TOTAL 0: 8:80 [0..7]: static fs metadata 0 (0..7) 8 <snip> 9: 8:80 [192..223]: 137 0..31 0 (192..223) 32 That's not right -- we asked what block maps block 208, and we should've received a mapping for inode 137 offset 16. Instead, we get nothing. The root cause of this problem is a mis-interaction between the fsmap code and how btree ranged queries work. xfs_btree_query_range returns any btree record that overlaps with the query interval, even if the record starts before or ends after the interval. Similarly, GETFSMAP is supposed to return a recordset containing all records that overlap the range queried. However, it's possible that the recordset is larger than the buffer that the caller provided to convey mappings to userspace. In /that/ case, userspace is supposed to copy the last record returned to fmh_keys[0] and call GETFSMAP again. In this case, we do not want to return mappings that we have already supplied to the caller. The call to xfs_btree_query_range is the same, but now we ignore any records that start before fmh_keys[0]. Unfortunately, we didn't implement the filtering predicate correctly. The predicate should only be called when we're calling back for more records. Accomplish this by setting info->low.rm_blockcount to a nonzero value and ensuring that it is cleared as necessary. As a result, we no longer want to adjust dkeys[0] in the main setup function because that's confusing. This patch doesn't touch the logdev/rtbitmap backends because they have bigger problems that will be addressed by subsequent patches. Found via xfs/556 with parent pointers enabled. Fixes: e89c041338ed ("xfs: implement the GETFSMAP ioctl") Signed-off-by: Darrick J. Wong <djwong(a)kernel.org> Reviewed-by: Dave Chinner <dchinner(a)redhat.com> Conflicts: fs/xfs/xfs_fsmap.c [Because there are many conflicting patches that need to be adapted, the in-place context adaptation is performed directly.] Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com> --- fs/xfs/xfs_fsmap.c | 67 +++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 595450a99ae2..deaed94011ad 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -161,7 +161,14 @@ struct xfs_getfsmap_info { u64 missing_owner; /* owner of holes */ u32 dev; /* device id */ xfs_agnumber_t agno; /* AG number, if applicable */ - struct xfs_rmap_irec low; /* low rmap key */ + /* + * Low rmap key for the query. If low.rm_blockcount is nonzero, this + * is the second (or later) call to retrieve the recordset in pieces. + * xfs_getfsmap_rec_before_start will compare all records retrieved + * by the rmapbt query to filter out any records that start before + * the last record. + */ + struct xfs_rmap_irec low; struct xfs_rmap_irec high; /* high rmap key */ bool last; /* last extent? */ }; @@ -237,6 +244,17 @@ xfs_getfsmap_format( xfs_fsmap_from_internal(rec, xfm); } +static inline bool +xfs_getfsmap_rec_before_start( + struct xfs_getfsmap_info *info, + const struct xfs_rmap_irec *rec, + xfs_daddr_t rec_daddr) +{ + if (info->low.rm_blockcount) + return xfs_rmap_compare(rec, &info->low) < 0; + return false; +} + /* * Format a reverse mapping for getfsmap, having translated rm_startblock * into the appropriate daddr units. @@ -260,7 +278,7 @@ xfs_getfsmap_helper( * Filter out records that start before our startpoint, if the * caller requested that. */ - if (xfs_rmap_compare(rec, &info->low) < 0) { + if (xfs_getfsmap_rec_before_start(info, rec, rec_daddr)) { rec_daddr += XFS_FSB_TO_BB(mp, rec->rm_blockcount); if (info->next_daddr < rec_daddr) info->next_daddr = rec_daddr; @@ -604,9 +622,27 @@ __xfs_getfsmap_datadev( error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); if (error) return error; - info->low.rm_blockcount = 0; + info->low.rm_blockcount = XFS_BB_TO_FSBT(mp, keys[0].fmr_length); xfs_getfsmap_set_irec_flags(&info->low, &keys[0]); + /* Adjust the low key if we are continuing from where we left off. */ + if (info->low.rm_blockcount == 0) { + /* empty */ + } else if (XFS_RMAP_NON_INODE_OWNER(info->low.rm_owner) || + (info->low.rm_flags & (XFS_RMAP_ATTR_FORK | + XFS_RMAP_BMBT_BLOCK | + XFS_RMAP_UNWRITTEN))) { + info->low.rm_startblock += info->low.rm_blockcount; + info->low.rm_owner = 0; + info->low.rm_offset = 0; + + start_fsb += info->low.rm_blockcount; + if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs) + return 0; + } else { + info->low.rm_offset += info->low.rm_blockcount; + } + info->high.rm_startblock = -1U; info->high.rm_owner = ULLONG_MAX; info->high.rm_offset = ULLONG_MAX; @@ -657,12 +693,8 @@ __xfs_getfsmap_datadev( * Set the AG low key to the start of the AG prior to * moving on to the next AG. */ - if (info->agno == start_ag) { - info->low.rm_startblock = 0; - info->low.rm_owner = 0; - info->low.rm_offset = 0; - info->low.rm_flags = 0; - } + if (info->agno == start_ag) + memset(&info->low, 0, sizeof(info->low)); } /* Report any gap at the end of the AG */ @@ -886,21 +918,17 @@ xfs_getfsmap( * blocks could be mapped to several other files/offsets. * According to rmapbt record ordering, the minimal next * possible record for the block range is the next starting - * offset in the same inode. Therefore, bump the file offset to - * continue the search appropriately. For all other low key - * mapping types (attr blocks, metadata), bump the physical - * offset as there can be no other mapping for the same physical - * block range. + * offset in the same inode. Therefore, each fsmap backend bumps + * the file offset to continue the search appropriately. For + * all other low key mapping types (attr blocks, metadata), each + * fsmap backend bumps the physical offset as there can be no + * other mapping for the same physical block range. */ dkeys[0] = head->fmh_keys[0]; if (dkeys[0].fmr_flags & (FMR_OF_SPECIAL_OWNER | FMR_OF_EXTENT_MAP)) { - dkeys[0].fmr_physical += dkeys[0].fmr_length; - dkeys[0].fmr_owner = 0; if (dkeys[0].fmr_offset) return -EINVAL; - } else - dkeys[0].fmr_offset += dkeys[0].fmr_length; - dkeys[0].fmr_length = 0; + } memset(&dkeys[1], 0xFF, sizeof(struct xfs_fsmap)); if (!xfs_getfsmap_check_keys(dkeys, &head->fmh_keys[1])) @@ -948,6 +976,7 @@ xfs_getfsmap( info.dev = handlers[i].dev; info.last = false; info.agno = NULLAGNUMBER; + info.low.rm_blockcount = 0; error = handlers[i].fn(tp, dkeys, &info); if (error) break; -- 2.39.2
2 1
0 0
[PATCH OLK-6.6] blk-iocost: do not WARN if iocg was already offlined
by Li Nan 11 Jun '24

11 Jun '24
mainline inclusion from mainline-v6.9-rc5 commit 01bc4fda9ea0a6b52f12326486f07a4910666cf6 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9UABH CVE: CVE-2024-36908 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- In iocg_pay_debt(), warn is triggered if 'active_list' is empty, which is intended to confirm iocg is active when it has debt. However, warn can be triggered during a blkcg or disk removal, if iocg_waitq_timer_fn() is run at that time: WARNING: CPU: 0 PID: 2344971 at block/blk-iocost.c:1402 iocg_pay_debt+0x14c/0x190 Call trace: iocg_pay_debt+0x14c/0x190 iocg_kick_waitq+0x438/0x4c0 iocg_waitq_timer_fn+0xd8/0x130 __run_hrtimer+0x144/0x45c __hrtimer_run_queues+0x16c/0x244 hrtimer_interrupt+0x2cc/0x7b0 The warn in this situation is meaningless. Since this iocg is being removed, the state of the 'active_list' is irrelevant, and 'waitq_timer' is canceled after removing 'active_list' in ioc_pd_free(), which ensures iocg is freed after iocg_waitq_timer_fn() returns. Therefore, add the check if iocg was already offlined to avoid warn when removing a blkcg or disk. Signed-off-by: Li Nan <linan122(a)huawei.com> Reviewed-by: Yu Kuai <yukuai3(a)huawei.com> Acked-by: Tejun Heo <tj(a)kernel.org> Link: https://lore.kernel.org/r/20240419093257.3004211-1-linan666@huaweicloud.com Signed-off-by: Jens Axboe <axboe(a)kernel.dk> Signed-off-by: Li Nan <linan122(a)huawei.com> --- block/blk-iocost.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 6a3e8a21c0fc..3ac79f0c098f 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -1439,8 +1439,11 @@ static void iocg_pay_debt(struct ioc_gq *iocg, u64 abs_vpay, lockdep_assert_held(&iocg->ioc->lock); lockdep_assert_held(&iocg->waitq.lock); - /* make sure that nobody messed with @iocg */ - WARN_ON_ONCE(list_empty(&iocg->active_list)); + /* + * make sure that nobody messed with @iocg. Check iocg->pd.online + * to avoid warn when removing blkcg or disk. + */ + WARN_ON_ONCE(list_empty(&iocg->active_list) && iocg->pd.online); WARN_ON_ONCE(iocg->inuse > 1); iocg->abs_vdebt -= min(abs_vpay, iocg->abs_vdebt); -- 2.39.2
2 1
0 0
[PATCH openEuler-22.03-LTS-SP1] gpiolib: cdev: Fix use after free in lineinfo_changed_notify
by Wupeng Ma 11 Jun '24

11 Jun '24
From: Zhongqiu Han <quic_zhonhan(a)quicinc.com> stable inclusion from stable-v6.6.31 commit 95ca7c90eaf5ea8a8460536535101e3e81160e2a category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9UG5Z CVE: CVE-2024-36899 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 02f6b0e1ec7e0e7d059dddc893645816552039da ] The use-after-free issue occurs as follows: when the GPIO chip device file is being closed by invoking gpio_chrdev_release(), watched_lines is freed by bitmap_free(), but the unregistration of lineinfo_changed_nb notifier chain failed due to waiting write rwsem. Additionally, one of the GPIO chip's lines is also in the release process and holds the notifier chain's read rwsem. Consequently, a race condition leads to the use-after-free of watched_lines. Here is the typical stack when issue happened: [free] gpio_chrdev_release() --> bitmap_free(cdev->watched_lines) <-- freed --> blocking_notifier_chain_unregister() --> down_write(&nh->rwsem) <-- waiting rwsem --> __down_write_common() --> rwsem_down_write_slowpath() --> schedule_preempt_disabled() --> schedule() [use] st54spi_gpio_dev_release() --> gpio_free() --> gpiod_free() --> gpiod_free_commit() --> gpiod_line_state_notify() --> blocking_notifier_call_chain() --> down_read(&nh->rwsem); <-- held rwsem --> notifier_call_chain() --> lineinfo_changed_notify() --> test_bit(xxxx, cdev->watched_lines) <-- use after free The side effect of the use-after-free issue is that a GPIO line event is being generated for userspace where it shouldn't. However, since the chrdev is being closed, userspace won't have the chance to read that event anyway. To fix the issue, call the bitmap_free() function after the unregistration of lineinfo_changed_nb notifier chain. Fixes: 51c1064e82e7 ("gpiolib: add new ioctl() for monitoring changes in line info") Signed-off-by: Zhongqiu Han <quic_zhonhan(a)quicinc.com> Link: https://lore.kernel.org/r/20240505141156.2944912-1-quic_zhonhan@quicinc.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski(a)linaro.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Conflicts: drivers/gpio/gpiolib-cdev.c [Ma Wupeng: context conflicts] Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com> --- drivers/gpio/gpiolib-cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 0f98a07efcd6..62666174a2c9 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2328,9 +2328,9 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file) struct gpio_chardev_data *cdev = file->private_data; struct gpio_device *gdev = cdev->gdev; - bitmap_free(cdev->watched_lines); blocking_notifier_chain_unregister(&gdev->notifier, &cdev->lineinfo_changed_nb); + bitmap_free(cdev->watched_lines); put_device(&gdev->dev); kfree(cdev); -- 2.25.1
2 1
0 0
[PATCH OLK-5.10] cvm_tsi: Fix security issue for Confidential cVM TSI
by Shengjie Li 11 Jun '24

11 Jun '24
virtcca inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IA45I1 -------------------------------- Fix security issue for Confidential cVM TSI: 1. Init TSI driver when config cvm_guest. 2. Modify the token structure to reduce the number of exposed variables. 3. Add a lock for obtaining the remote attestation report. Fixes: 31071f4b2a0b ("cvm_tsi: add cvm tsi interface") Signed-off-by: Shengjie Li <lishengjie12(a)huawei.com> --- arch/arm64/include/asm/cvm_smc.h | 22 +++---- arch/arm64/include/uapi/asm/cvm_tsi.h | 11 ++-- arch/arm64/kernel/cvm_tsi.c | 89 ++++++++++++++------------- 3 files changed, 64 insertions(+), 58 deletions(-) diff --git a/arch/arm64/include/asm/cvm_smc.h b/arch/arm64/include/asm/cvm_smc.h index c4d56333e3..91688bc169 100644 --- a/arch/arm64/include/asm/cvm_smc.h +++ b/arch/arm64/include/asm/cvm_smc.h @@ -124,30 +124,30 @@ static inline unsigned long tsi_measurement_read(struct cvm_measurement *cvm_mea return res.a0; } -static inline unsigned long tsi_attestation_token_init(struct cvm_attestation_cmd *attest_cmd) +static inline unsigned long tsi_attestation_token_init(unsigned char *challenge) { struct arm_smccc_res res; - unsigned char *challenge; + unsigned char *buf; - challenge = kmalloc(CHALLENGE_SIZE, GFP_KERNEL); - if (!challenge) + buf = kmalloc(CHALLENGE_SIZE, GFP_KERNEL); + if (!buf) return -ENOMEM; - memcpy(challenge, attest_cmd->challenge, CHALLENGE_SIZE); + memcpy(buf, challenge, CHALLENGE_SIZE); - arm_smccc_1_1_smc(SMC_TSI_ATTESTATION_TOKEN_INIT, virt_to_phys(challenge), &res); - kfree(challenge); + arm_smccc_1_1_smc(SMC_TSI_ATTESTATION_TOKEN_INIT, virt_to_phys(buf), &res); + kfree(buf); return res.a0; } -static inline unsigned long tsi_attestation_token_continue(struct cvm_attestation_cmd *attest_cmd) +static inline unsigned long tsi_attestation_token_continue(struct cvm_token_granule *token_granule) { struct arm_smccc_res res; - arm_smccc_1_1_smc(SMC_TSI_ATTESTATION_TOKEN_CONTINUE, virt_to_phys(attest_cmd->granule_ipa), - attest_cmd->offset, attest_cmd->size, &res); + arm_smccc_1_1_smc(SMC_TSI_ATTESTATION_TOKEN_CONTINUE, virt_to_phys(token_granule->ipa), + token_granule->offset, token_granule->size, &res); - attest_cmd->num_wr_bytes = res.a1; + token_granule->num_wr_bytes = res.a1; return res.a0; } diff --git a/arch/arm64/include/uapi/asm/cvm_tsi.h b/arch/arm64/include/uapi/asm/cvm_tsi.h index 43e17a0da0..1ed4386db2 100644 --- a/arch/arm64/include/uapi/asm/cvm_tsi.h +++ b/arch/arm64/include/uapi/asm/cvm_tsi.h @@ -55,10 +55,13 @@ struct cvm_measurement_extend { struct cvm_attestation_cmd { unsigned char challenge[CHALLENGE_SIZE]; /* input: challenge value */ - unsigned long token_size; /* return: challenge value */ - void *granule_head; - void *granule_ipa; /* IPA of the Granule to which the token will be written */ - unsigned long granule_count; + unsigned long token_size; /* return: token size */ +}; + +struct cvm_token_granule { + void *head; + void *ipa; /* IPA of the Granule to which the token will be written */ + unsigned long count; unsigned long offset; /* Offset within Granule to start of buffer in bytes */ unsigned long size; /* Size of buffer in bytes */ unsigned long num_wr_bytes; /* Number of bytes written to buffer */ diff --git a/arch/arm64/kernel/cvm_tsi.c b/arch/arm64/kernel/cvm_tsi.c index b48e5b17f4..252fe5352a 100644 --- a/arch/arm64/kernel/cvm_tsi.c +++ b/arch/arm64/kernel/cvm_tsi.c @@ -4,6 +4,7 @@ #include <linux/slab.h> #include <linux/miscdevice.h> #include <linux/preempt.h> +#include <asm/cvm_guest.h> #include <asm/cvm_smc.h> #include <asm/cvm_tsi.h> @@ -16,20 +17,19 @@ struct attestation_token { static struct attestation_token token; +static DEFINE_SPINLOCK(lock); + static long tmm_tsi_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static int tmm_tsi_release(struct inode *inode, struct file *file); static ssize_t tmm_token_read(struct file *file, char __user *user_buffer, size_t size, loff_t *offset); static int tmm_get_tsi_version(struct cvm_tsi_version __user *arg); -static int tmm_get_attestation_token(struct cvm_attestation_cmd __user *arg, - struct attestation_token *attest_token); +static int tmm_get_attestation_token(struct cvm_attestation_cmd __user *arg); static int tmm_get_device_cert(struct cca_device_cert __user *arg); static const struct file_operations tmm_tsi_fops = { .owner = THIS_MODULE, .read = tmm_token_read, - .release = tmm_tsi_release, .unlocked_ioctl = tmm_tsi_ioctl }; @@ -44,6 +44,9 @@ static int __init tmm_tsi_init(void) unsigned long ver; int ret; + if (!is_cvm_world()) + return -EIO; + ver = tsi_get_version(); if (ver == SMCCC_RET_NOT_SUPPORTED) { pr_err("tmm_tsi: SMC return not supported!\n"); @@ -56,6 +59,11 @@ static int __init tmm_tsi_init(void) return ret; } + /* Allocate a large memory */ + token.buf = kmalloc(GRANULE_SIZE * MAX_TOKEN_GRANULE_PAGE, GFP_KERNEL); + if (!token.buf) + return -ENOMEM; + pr_warn("tmm_tsi: module loaded (version %lu.%lu).\n", TSI_ABI_VERSION_GET_MAJOR(ver), TSI_ABI_VERSION_GET_MINOR(ver)); @@ -65,8 +73,10 @@ static int __init tmm_tsi_init(void) static void __exit tmm_tsi_exit(void) { - if (token.buf != NULL) + if (token.buf != NULL) { + memset(token.buf, 0, GRANULE_SIZE * MAX_TOKEN_GRANULE_PAGE); kfree(token.buf); + } misc_deregister(&ioctl_dev); pr_warn("tmm_tsi: module unloaded.\n"); } @@ -80,7 +90,7 @@ static long tmm_tsi_ioctl(struct file *file, unsigned int cmd, unsigned long arg ret = tmm_get_tsi_version((struct cvm_tsi_version *)arg); break; case TMM_GET_ATTESTATION_TOKEN: - ret = tmm_get_attestation_token((struct cvm_attestation_cmd *)arg, &token); + ret = tmm_get_attestation_token((struct cvm_attestation_cmd *)arg); break; case TMM_GET_DEVICE_CERT: ret = tmm_get_device_cert((struct cca_device_cert *)arg); @@ -99,28 +109,25 @@ static ssize_t tmm_token_read(struct file *file, char __user *user_buffer, int ret; int to_copy; - if (*offset >= token.size) + spin_lock(&lock); + if (*offset >= token.size) { + spin_unlock(&lock); return 0; + } to_copy = min((int)size, (int)(token.size - *offset)); ret = copy_to_user(user_buffer, token.buf + *offset, to_copy); if (ret) { pr_err("tmm_tsi: copy token to user failed (%d)!\n", ret); + spin_unlock(&lock); return -1; } *offset += to_copy; + spin_unlock(&lock); return to_copy; } -static int tmm_tsi_release(struct inode *inode, struct file *file) -{ - if (token.buf != NULL) { - memset(token.buf, 0, GRANULE_SIZE * MAX_TOKEN_GRANULE_PAGE); - kfree(token.buf); - } - return 0; -} static int tmm_get_tsi_version(struct cvm_tsi_version __user *arg) { @@ -141,65 +148,61 @@ static int tmm_get_tsi_version(struct cvm_tsi_version __user *arg) return 0; } -static int tmm_get_attestation_token(struct cvm_attestation_cmd __user *arg, - struct attestation_token *attest_token) +static int tmm_get_attestation_token(struct cvm_attestation_cmd __user *arg) { unsigned long ret; - struct cvm_attestation_cmd cmd = {0}; + struct cvm_token_granule token_granule = {0}; + unsigned char challenge[CHALLENGE_SIZE]; - ret = copy_from_user(&(cmd.challenge), &(arg->challenge), sizeof(cmd.challenge)); + ret = copy_from_user(challenge, &(arg->challenge), CHALLENGE_SIZE); if (ret) { pr_err("tmm_tsi: copy data from user failed (%lu)!\n", ret); return -EFAULT; } - /* Allocate a large memory */ - attest_token->buf = kmalloc(GRANULE_SIZE * MAX_TOKEN_GRANULE_PAGE, GFP_KERNEL); - if (!attest_token->buf) - return -ENOMEM; - cmd.granule_head = attest_token->buf; - cmd.granule_ipa = cmd.granule_head; + spin_lock(&lock); + token_granule.head = token.buf; + token_granule.ipa = token_granule.head; - /* preempt_disable(); */ - - ret = tsi_attestation_token_init(&cmd); + ret = tsi_attestation_token_init(challenge); if (ret) { pr_err("tmm_tsi: tsi call tsi_attestation_token_init failed (%lu)!\n", ret); + spin_unlock(&lock); return -EIO; } do { /* Retrieve one Granule of data per loop iteration */ - cmd.granule_ipa = cmd.granule_head + - (unsigned long)(cmd.granule_count * GRANULE_SIZE); - cmd.offset = 0; + token_granule.ipa = token_granule.head + + (unsigned long)(token_granule.count * GRANULE_SIZE); + token_granule.offset = 0; do { /* Retrieve sub-Granule chunk of data per loop iteration */ - cmd.size = GRANULE_SIZE - cmd.offset; - ret = tsi_attestation_token_continue(&cmd); - cmd.offset += cmd.num_wr_bytes; - } while (ret == TSI_INCOMPLETE && cmd.offset < GRANULE_SIZE); + token_granule.size = GRANULE_SIZE - token_granule.offset; + ret = tsi_attestation_token_continue(&token_granule); + token_granule.offset += token_granule.num_wr_bytes; + } while (ret == TSI_INCOMPLETE && token_granule.offset < GRANULE_SIZE); - cmd.granule_count += 1; - if (cmd.granule_count >= MAX_TOKEN_GRANULE_PAGE && ret == TSI_INCOMPLETE) { + token_granule.count += 1; + if (token_granule.count >= MAX_TOKEN_GRANULE_PAGE && ret == TSI_INCOMPLETE) { pr_err("tmm_tsi: macro MAX_TOKEN_GRANULE_PAGE (%d) is too small!\n", MAX_TOKEN_GRANULE_PAGE); + spin_unlock(&lock); return -ENOMEM; } } while (ret == TSI_INCOMPLETE); - /* preempt_enable(); */ - /* Send to user space the total size of the token */ - cmd.granule_count = cmd.granule_count - 1; - cmd.token_size = (unsigned long)(GRANULE_SIZE * cmd.granule_count) + cmd.offset; - attest_token->size = cmd.token_size; + token_granule.count = token_granule.count - 1; + token.size = (unsigned long)(GRANULE_SIZE * token_granule.count) + token_granule.offset; - ret = copy_to_user(&(arg->token_size), &(cmd.token_size), sizeof(cmd.token_size)); + ret = copy_to_user(&(arg->token_size), &(token.size), sizeof(token.size)); if (ret) { pr_err("tmm_tsi: copy data to user failed (%lu)!\n", ret); + spin_unlock(&lock); return -EFAULT; } + spin_unlock(&lock); return 0; } -- 2.37.2.windows.2
2 1
0 0
[PATCH openEuler-1.0-LTS] nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet
by Zheng Zucheng 11 Jun '24

11 Jun '24
From: Ryosuke Yasuoka <ryasuoka(a)redhat.com> stable inclusion from stable-v6.6.26 commit a946ebee45b09294c8b0b0e77410b763c4d2817a category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9QG8F CVE: CVE-2024-35915 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit d24b03535e5eb82e025219c2f632b485409c898f ] syzbot reported the following uninit-value access issue [1][2]: nci_rx_work() parses and processes received packet. When the payload length is zero, each message type handler reads uninitialized payload and KMSAN detects this issue. The receipt of a packet with a zero-size payload is considered unexpected, and therefore, such packets should be silently discarded. This patch resolved this issue by checking payload size before calling each message type handler codes. Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation") Reported-and-tested-by: syzbot+7ea9413ea6749baf5574(a)syzkaller.appspotmail.com Reported-and-tested-by: syzbot+29b5ca705d2e0f4a44d2(a)syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=7ea9413ea6749baf5574 [1] Closes: https://syzkaller.appspot.com/bug?extid=29b5ca705d2e0f4a44d2 [2] Signed-off-by: Ryosuke Yasuoka <ryasuoka(a)redhat.com> Reviewed-by: Jeremy Cline <jeremy(a)jcline.org> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski(a)linaro.org> Signed-off-by: David S. Miller <davem(a)davemloft.net> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: ZhangPeng <zhangpeng362(a)huawei.com> Signed-off-by: Zheng Zucheng <zhengzucheng(a)huawei.com> --- net/nfc/nci/core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 7148bc0af030..f393aae80598 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -1507,6 +1507,11 @@ static void nci_rx_work(struct work_struct *work) nfc_send_to_raw_sock(ndev->nfc_dev, skb, RAW_PAYLOAD_NCI, NFC_DIRECTION_RX); + if (!nci_plen(skb->data)) { + kfree_skb(skb); + break; + } + /* Process frame */ switch (nci_mt(skb->data)) { case NCI_MT_RSP_PKT: -- 2.34.1
2 1
0 0
[PATCH openEuler-22.03-LTS-SP1] net/mlx5e: Fix use-after-free of encap entry in neigh update handler
by Zhang Changzhong 11 Jun '24

11 Jun '24
From: Vlad Buslov <vladbu(a)nvidia.com> mainline inclusion from mainline-v5.13-rc7 commit fb1a3132ee1ac968316e45d21a48703a6db0b6c3 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9R4FV CVE: CVE-2021-47247 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- Function mlx5e_rep_neigh_update() wasn't updated to accommodate rtnl lock removal from TC filter update path and properly handle concurrent encap entry insertion/deletion which can lead to following use-after-free: [23827.464923] ================================================================== [23827.469446] BUG: KASAN: use-after-free in mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.470971] Read of size 4 at addr ffff8881d132228c by task kworker/u20:6/21635 [23827.472251] [23827.472615] CPU: 9 PID: 21635 Comm: kworker/u20:6 Not tainted 5.13.0-rc3+ #5 [23827.473788] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [23827.475639] Workqueue: mlx5e mlx5e_rep_neigh_update [mlx5_core] [23827.476731] Call Trace: [23827.477260] dump_stack+0xbb/0x107 [23827.477906] print_address_description.constprop.0+0x18/0x140 [23827.478896] ? mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.479879] ? mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.480905] kasan_report.cold+0x7c/0xd8 [23827.481701] ? mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.482744] kasan_check_range+0x145/0x1a0 [23827.493112] mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.494054] ? mlx5e_tc_tun_encap_info_equal_generic+0x140/0x140 [mlx5_core] [23827.495296] mlx5e_rep_neigh_update+0x41e/0x5e0 [mlx5_core] [23827.496338] ? mlx5e_rep_neigh_entry_release+0xb80/0xb80 [mlx5_core] [23827.497486] ? read_word_at_a_time+0xe/0x20 [23827.498250] ? strscpy+0xa0/0x2a0 [23827.498889] process_one_work+0x8ac/0x14e0 [23827.499638] ? lockdep_hardirqs_on_prepare+0x400/0x400 [23827.500537] ? pwq_dec_nr_in_flight+0x2c0/0x2c0 [23827.501359] ? rwlock_bug.part.0+0x90/0x90 [23827.502116] worker_thread+0x53b/0x1220 [23827.502831] ? process_one_work+0x14e0/0x14e0 [23827.503627] kthread+0x328/0x3f0 [23827.504254] ? _raw_spin_unlock_irq+0x24/0x40 [23827.505065] ? __kthread_bind_mask+0x90/0x90 [23827.505912] ret_from_fork+0x1f/0x30 [23827.506621] [23827.506987] Allocated by task 28248: [23827.507694] kasan_save_stack+0x1b/0x40 [23827.508476] __kasan_kmalloc+0x7c/0x90 [23827.509197] mlx5e_attach_encap+0xde1/0x1d40 [mlx5_core] [23827.510194] mlx5e_tc_add_fdb_flow+0x397/0xc40 [mlx5_core] [23827.511218] __mlx5e_add_fdb_flow+0x519/0xb30 [mlx5_core] [23827.512234] mlx5e_configure_flower+0x191c/0x4870 [mlx5_core] [23827.513298] tc_setup_cb_add+0x1d5/0x420 [23827.514023] fl_hw_replace_filter+0x382/0x6a0 [cls_flower] [23827.514975] fl_change+0x2ceb/0x4a51 [cls_flower] [23827.515821] tc_new_tfilter+0x89a/0x2070 [23827.516548] rtnetlink_rcv_msg+0x644/0x8c0 [23827.517300] netlink_rcv_skb+0x11d/0x340 [23827.518021] netlink_unicast+0x42b/0x700 [23827.518742] netlink_sendmsg+0x743/0xc20 [23827.519467] sock_sendmsg+0xb2/0xe0 [23827.520131] ____sys_sendmsg+0x590/0x770 [23827.520851] ___sys_sendmsg+0xd8/0x160 [23827.521552] __sys_sendmsg+0xb7/0x140 [23827.522238] do_syscall_64+0x3a/0x70 [23827.522907] entry_SYSCALL_64_after_hwframe+0x44/0xae [23827.523797] [23827.524163] Freed by task 25948: [23827.524780] kasan_save_stack+0x1b/0x40 [23827.525488] kasan_set_track+0x1c/0x30 [23827.526187] kasan_set_free_info+0x20/0x30 [23827.526968] __kasan_slab_free+0xed/0x130 [23827.527709] slab_free_freelist_hook+0xcf/0x1d0 [23827.528528] kmem_cache_free_bulk+0x33a/0x6e0 [23827.529317] kfree_rcu_work+0x55f/0xb70 [23827.530024] process_one_work+0x8ac/0x14e0 [23827.530770] worker_thread+0x53b/0x1220 [23827.531480] kthread+0x328/0x3f0 [23827.532114] ret_from_fork+0x1f/0x30 [23827.532785] [23827.533147] Last potentially related work creation: [23827.534007] kasan_save_stack+0x1b/0x40 [23827.534710] kasan_record_aux_stack+0xab/0xc0 [23827.535492] kvfree_call_rcu+0x31/0x7b0 [23827.536206] mlx5e_tc_del_fdb_flow+0x577/0xef0 [mlx5_core] [23827.537305] mlx5e_flow_put+0x49/0x80 [mlx5_core] [23827.538290] mlx5e_delete_flower+0x6d1/0xe60 [mlx5_core] [23827.539300] tc_setup_cb_destroy+0x18e/0x2f0 [23827.540144] fl_hw_destroy_filter+0x1d2/0x310 [cls_flower] [23827.541148] __fl_delete+0x4dc/0x660 [cls_flower] [23827.541985] fl_delete+0x97/0x160 [cls_flower] [23827.542782] tc_del_tfilter+0x7ab/0x13d0 [23827.543503] rtnetlink_rcv_msg+0x644/0x8c0 [23827.544257] netlink_rcv_skb+0x11d/0x340 [23827.544981] netlink_unicast+0x42b/0x700 [23827.545700] netlink_sendmsg+0x743/0xc20 [23827.546424] sock_sendmsg+0xb2/0xe0 [23827.547084] ____sys_sendmsg+0x590/0x770 [23827.547850] ___sys_sendmsg+0xd8/0x160 [23827.548606] __sys_sendmsg+0xb7/0x140 [23827.549303] do_syscall_64+0x3a/0x70 [23827.549969] entry_SYSCALL_64_after_hwframe+0x44/0xae [23827.550853] [23827.551217] The buggy address belongs to the object at ffff8881d1322200 [23827.551217] which belongs to the cache kmalloc-256 of size 256 [23827.553341] The buggy address is located 140 bytes inside of [23827.553341] 256-byte region [ffff8881d1322200, ffff8881d1322300) [23827.555747] The buggy address belongs to the page: [23827.556847] page:00000000898762aa refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1d1320 [23827.558651] head:00000000898762aa order:2 compound_mapcount:0 compound_pincount:0 [23827.559961] flags: 0x2ffff800010200(slab|head|node=0|zone=2|lastcpupid=0x1ffff) [23827.561243] raw: 002ffff800010200 dead000000000100 dead000000000122 ffff888100042b40 [23827.562653] raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000 [23827.564112] page dumped because: kasan: bad access detected [23827.565439] [23827.565932] Memory state around the buggy address: [23827.566917] ffff8881d1322180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [23827.568485] ffff8881d1322200: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [23827.569818] >ffff8881d1322280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [23827.571143] ^ [23827.571879] ffff8881d1322300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [23827.573283] ffff8881d1322380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [23827.574654] ================================================================== Most of the necessary logic is already correctly implemented by mlx5e_get_next_valid_encap() helper that is used in neigh stats update handler. Make the handler generic by renaming it to mlx5e_get_next_matching_encap() and use callback to test whether flow is matching instead of hardcoded check for 'valid' flag value. Implement mlx5e_get_next_valid_encap() by calling mlx5e_get_next_matching_encap() with callback that tests encap MLX5_ENCAP_ENTRY_VALID flag. Implement new mlx5e_get_next_init_encap() helper by calling mlx5e_get_next_matching_encap() with callback that tests encap completion result to be non-error and use it in mlx5e_rep_neigh_update() to safely iterate over nhe->encap_list. Remove encap completion logic from mlx5e_rep_update_flows() since the encap entries passed to this function are already guaranteed to be properly initialized by similar code in mlx5e_get_next_init_encap(). Fixes: 2a1f1768fa17 ("net/mlx5e: Refactor neigh update for concurrent execution") Signed-off-by: Vlad Buslov <vladbu(a)nvidia.com> Reviewed-by: Roi Dayan <roid(a)nvidia.com> Signed-off-by: Saeed Mahameed <saeedm(a)nvidia.com> Conflicts: drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c drivers/net/ethernet/mellanox/mlx5/core/en_tc.c drivers/net/ethernet/mellanox/mlx5/core/en_tc.h [Adjust context because patchset 08cbabb77e90 ("Merge tag 'mlx5-updates-2021-02-04' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux") not merged] Signed-off-by: Zhang Changzhong <zhangchangzhong(a)huawei.com> --- .../net/ethernet/mellanox/mlx5/core/en/rep/neigh.c | 15 ++++------ .../net/ethernet/mellanox/mlx5/core/en/rep/tc.c | 6 +--- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 33 ++++++++++++++++++++-- drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 3 ++ 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c index 58e2703..bbc182e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c @@ -129,9 +129,8 @@ static void mlx5e_rep_neigh_update(struct work_struct *work) work); struct mlx5e_neigh_hash_entry *nhe = update_work->nhe; struct neighbour *n = update_work->n; - struct mlx5e_encap_entry *e; + struct mlx5e_encap_entry *e = NULL; unsigned char ha[ETH_ALEN]; - struct mlx5e_priv *priv; bool neigh_connected; u8 nud_state, dead; @@ -152,14 +151,12 @@ static void mlx5e_rep_neigh_update(struct work_struct *work) trace_mlx5e_rep_neigh_update(nhe, ha, neigh_connected); - list_for_each_entry(e, &nhe->encap_list, encap_list) { - if (!mlx5e_encap_take(e)) - continue; + /* mlx5e_get_next_init_encap() releases previous encap before returning + * the next one. + */ + while ((e = mlx5e_get_next_init_encap(nhe, e)) != NULL) + mlx5e_rep_update_flows(netdev_priv(e->out_dev), e, neigh_connected, ha); - priv = netdev_priv(e->out_dev); - mlx5e_rep_update_flows(priv, e, neigh_connected, ha); - mlx5e_encap_put(priv, e); - } rtnl_unlock(); mlx5e_release_neigh_update_work(update_work); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c index 2fdea05..552c07e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c @@ -91,13 +91,9 @@ void mlx5e_rep_update_flows(struct mlx5e_priv *priv, ASSERT_RTNL(); - /* wait for encap to be fully initialized */ - wait_for_completion(&e->res_ready); - mutex_lock(&esw->offloads.encap_tbl_lock); encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID); - if (e->compl_result < 0 || (encap_connected == neigh_connected && - ether_addr_equal(e->h_dest, ha))) + if (encap_connected == neigh_connected && ether_addr_equal(e->h_dest, ha)) goto unlock; mlx5e_take_all_encap_flows(e, &flow_list); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 1ad1692..f5a3078 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1647,9 +1647,12 @@ void mlx5e_put_encap_flow_list(struct mlx5e_priv *priv, struct list_head *flow_l mlx5e_flow_put(priv, flow); } +typedef bool (match_cb)(struct mlx5e_encap_entry *); + static struct mlx5e_encap_entry * -mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe, - struct mlx5e_encap_entry *e) +mlx5e_get_next_matching_encap(struct mlx5e_neigh_hash_entry *nhe, + struct mlx5e_encap_entry *e, + match_cb match) { struct mlx5e_encap_entry *next = NULL; @@ -1684,7 +1687,7 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe, /* wait for encap to be fully initialized */ wait_for_completion(&next->res_ready); /* continue searching if encap entry is not in valid state after completion */ - if (!(next->flags & MLX5_ENCAP_ENTRY_VALID)) { + if (!match(next)) { e = next; goto retry; } @@ -1692,6 +1695,30 @@ mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe, return next; } +static bool mlx5e_encap_valid(struct mlx5e_encap_entry *e) +{ + return e->flags & MLX5_ENCAP_ENTRY_VALID; +} + +static struct mlx5e_encap_entry * +mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe, + struct mlx5e_encap_entry *e) +{ + return mlx5e_get_next_matching_encap(nhe, e, mlx5e_encap_valid); +} + +static bool mlx5e_encap_initialized(struct mlx5e_encap_entry *e) +{ + return e->compl_result >= 0; +} + +struct mlx5e_encap_entry * +mlx5e_get_next_init_encap(struct mlx5e_neigh_hash_entry *nhe, + struct mlx5e_encap_entry *e) +{ + return mlx5e_get_next_matching_encap(nhe, e, mlx5e_encap_initialized); +} + void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) { struct mlx5e_neigh *m_neigh = &nhe->m_neigh; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h index 4a2ce24..e7e5f0c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h @@ -161,6 +161,9 @@ void mlx5e_take_all_encap_flows(struct mlx5e_encap_entry *e, struct list_head *f void mlx5e_put_encap_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list); struct mlx5e_neigh_hash_entry; +struct mlx5e_encap_entry * +mlx5e_get_next_init_encap(struct mlx5e_neigh_hash_entry *nhe, + struct mlx5e_encap_entry *e); void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe); void mlx5e_tc_reoffload_flows_work(struct work_struct *work); -- 2.9.5
2 1
0 0
[PATCH OLK-5.10] gpiolib: cdev: Fix use after free in lineinfo_changed_notify
by Wupeng Ma 11 Jun '24

11 Jun '24
From: Zhongqiu Han <quic_zhonhan(a)quicinc.com> stable inclusion from stable-v6.6.31 commit 95ca7c90eaf5ea8a8460536535101e3e81160e2a category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9UG5Z CVE: CVE-2024-36899 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 02f6b0e1ec7e0e7d059dddc893645816552039da ] The use-after-free issue occurs as follows: when the GPIO chip device file is being closed by invoking gpio_chrdev_release(), watched_lines is freed by bitmap_free(), but the unregistration of lineinfo_changed_nb notifier chain failed due to waiting write rwsem. Additionally, one of the GPIO chip's lines is also in the release process and holds the notifier chain's read rwsem. Consequently, a race condition leads to the use-after-free of watched_lines. Here is the typical stack when issue happened: [free] gpio_chrdev_release() --> bitmap_free(cdev->watched_lines) <-- freed --> blocking_notifier_chain_unregister() --> down_write(&nh->rwsem) <-- waiting rwsem --> __down_write_common() --> rwsem_down_write_slowpath() --> schedule_preempt_disabled() --> schedule() [use] st54spi_gpio_dev_release() --> gpio_free() --> gpiod_free() --> gpiod_free_commit() --> gpiod_line_state_notify() --> blocking_notifier_call_chain() --> down_read(&nh->rwsem); <-- held rwsem --> notifier_call_chain() --> lineinfo_changed_notify() --> test_bit(xxxx, cdev->watched_lines) <-- use after free The side effect of the use-after-free issue is that a GPIO line event is being generated for userspace where it shouldn't. However, since the chrdev is being closed, userspace won't have the chance to read that event anyway. To fix the issue, call the bitmap_free() function after the unregistration of lineinfo_changed_nb notifier chain. Fixes: 51c1064e82e7 ("gpiolib: add new ioctl() for monitoring changes in line info") Signed-off-by: Zhongqiu Han <quic_zhonhan(a)quicinc.com> Link: https://lore.kernel.org/r/20240505141156.2944912-1-quic_zhonhan@quicinc.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski(a)linaro.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Conflicts: drivers/gpio/gpiolib-cdev.c [Ma Wupeng: context conflicts] Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com> --- drivers/gpio/gpiolib-cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 40d0196d8bdc..b273cb988aec 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2345,9 +2345,9 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file) struct gpio_chardev_data *cdev = file->private_data; struct gpio_device *gdev = cdev->gdev; - bitmap_free(cdev->watched_lines); blocking_notifier_chain_unregister(&gdev->notifier, &cdev->lineinfo_changed_nb); + bitmap_free(cdev->watched_lines); put_device(&gdev->dev); kfree(cdev); -- 2.25.1
2 1
0 0
  • ← Newer
  • 1
  • ...
  • 905
  • 906
  • 907
  • 908
  • 909
  • 910
  • 911
  • ...
  • 1876
  • Older →

HyperKitty Powered by HyperKitty