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
  • ----- 2026 -----
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • 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

  • 43 participants
  • 24866 discussions
[PATCH openEuler-1.0-LTS] configfs: fix lockless traversals of ->s_children
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v7.2-rc1 commit 9b9e8bb81c41fd27e7b57a1c936fde140548535f category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18047 CVE: CVE-2026-74330 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- Having the parent directory locked protects entries from removal by another thread, but it does *not* protect cursors from being moved around by lseek() - or freed, for that matter. Fixes: 6f6107640625 ("configfs: Introduce configfs_dirent_lock") Reviewed-by: Jan Kara <jack(a)suse.cz> Signed-off-by: Al Viro <viro(a)zeniv.linux.org.uk> Conflicts: fs/configfs/dir.c [Context conflicts.] Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/configfs/dir.c | 54 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 687735be3cd4..776ca9d80b48 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -242,15 +242,16 @@ static int configfs_dirent_exists(struct configfs_dirent *parent_sd, { struct configfs_dirent * sd; + spin_lock(&configfs_dirent_lock); list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { if (sd->s_element) { - const unsigned char *existing = configfs_get_name(sd); - if (strcmp(existing, new)) - continue; - else + if (strcmp(configfs_get_name(sd), new) == 0) { + spin_unlock(&configfs_dirent_lock); return -EEXIST; + } } } + spin_unlock(&configfs_dirent_lock); return 0; } @@ -562,11 +563,28 @@ static void configfs_detach_rollback(struct dentry *dentry) configfs_detach_rollback(sd->s_dentry); } +/* + * Find the next non-cursor. configfs_dirent_lock held by caller. + */ +static struct configfs_dirent *next_dirent(struct configfs_dirent *parent, + struct configfs_dirent *last) +{ + struct configfs_dirent *s; + + s = list_prepare_entry(last, &parent->s_children, s_sibling); + + list_for_each_entry_continue(s, &parent->s_children, s_sibling) { + if (s->s_element) + return s; + } + return NULL; +} + static void detach_attrs(struct config_item * item) { struct dentry * dentry = dget(item->ci_dentry); - struct configfs_dirent * parent_sd; - struct configfs_dirent * sd, * tmp; + struct configfs_dirent *parent_sd; + struct configfs_dirent *sd, *next; if (!dentry) return; @@ -575,15 +593,19 @@ static void detach_attrs(struct config_item * item) dentry->d_name.name); parent_sd = dentry->d_fsdata; - list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { - if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED)) + + spin_lock(&configfs_dirent_lock); + for (sd = next_dirent(parent_sd, NULL); sd; sd = next) { + next = next_dirent(parent_sd, sd); + if (!(sd->s_type & CONFIGFS_NOT_PINNED)) continue; - spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); spin_unlock(&configfs_dirent_lock); configfs_drop_dentry(sd, dentry); configfs_put(sd); + spin_lock(&configfs_dirent_lock); } + spin_unlock(&configfs_dirent_lock); /** * Drop reference from dget() on entrance. @@ -632,18 +654,20 @@ static void detach_groups(struct config_group *group) struct dentry * dentry = dget(group->cg_item.ci_dentry); struct dentry *child; struct configfs_dirent *parent_sd; - struct configfs_dirent *sd, *tmp; + struct configfs_dirent *sd, *next; if (!dentry) return; parent_sd = dentry->d_fsdata; - list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { - if (!sd->s_element || - !(sd->s_type & CONFIGFS_USET_DEFAULT)) + spin_lock(&configfs_dirent_lock); + for (sd = next_dirent(parent_sd, NULL); sd; sd = next) { + next = next_dirent(parent_sd, sd); + if (!(sd->s_type & CONFIGFS_USET_DEFAULT)) continue; child = sd->s_dentry; + spin_unlock(&configfs_dirent_lock); inode_lock(d_inode(child)); @@ -655,7 +679,9 @@ static void detach_groups(struct config_group *group) d_delete(child); dput(child); + spin_lock(&configfs_dirent_lock); } + spin_unlock(&configfs_dirent_lock); /** * Drop reference from dget() on entrance. @@ -1107,6 +1133,7 @@ configfs_find_subsys_dentry(struct configfs_dirent *root_sd, struct configfs_dirent *p; struct configfs_dirent *ret = NULL; + spin_lock(&configfs_dirent_lock); list_for_each_entry(p, &root_sd->s_children, s_sibling) { if (p->s_type & CONFIGFS_DIR && p->s_element == subsys_item) { @@ -1114,6 +1141,7 @@ configfs_find_subsys_dentry(struct configfs_dirent *root_sd, break; } } + spin_unlock(&configfs_dirent_lock); return ret; } -- 2.52.0
2 1
0 0
[PATCH openEuler-1.0-LTS 0/2] ovl: check access to copy_file_range source with src mounter creds
by Ran Hongyun 04 Sep '26

04 Sep '26
Export rw_verify_area and check access to copy_file_range source with src mounter creds. Patch 1 export rw_verify_area for verification. Patch 2 check access to copy_file_range source with src mounter creds Ran Hongyun (2): fs: export rw_verify_area() ovl: check access to copy_file_range source with src mounter creds fs/internal.h | 4 ---- fs/overlayfs/file.c | 17 +++++++++++++++++ fs/read_write.c | 1 + include/linux/fs.h | 1 + 4 files changed, 19 insertions(+), 4 deletions(-) -- 2.52.0
2 1
0 0
[PATCH OLK-5.10] configfs_lookup(): don't leave ->s_dentry dangling on failure
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v7.2-rc1 commit 10da12d352b7b2bb330a8609fdda9a58bf0e9856 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18161 CVE: CVE-2026-74359 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- Normally ->s_dentry is cleared when dentry it's pointing to becomes negative (on eviction, realistically). However, that only happens if dentry gets to be positive in the first place; in case of inode allocation failure dentry never becomes positive, so ->d_iput() is not called at all. We do part of what normally would've been done by configfs_d_iput() (dropping the reference to configfs_dirent) manually, but we do not clear ->s_dentry there. Sloppy as it is, it does not matter in case of configfs_create_{dir,link}() - there configfs_dirent does not survive dropping the sole reference to it. However, for configfs_lookup() it *does* survive, with a dangling pointer to soon to be freed dentry sitting it its ->s_dentry. Subsequent getdents(2) in that directory will end up dereferencing that pointer in order to pick the inode number. Use after free... This is the minimal fix; the right approach is to set the linkage between dentry and configfs_dirent only after we know that we have an inode, but that takes more surgery and the bug had been there since 2006, so... Fixes: 3d0f89bb1694 ("configfs: Add permission and ownership to configfs objects") # 2.6.16-rc3 Reviewed-by: Jan Kara <jack(a)suse.cz> Reviewed-by: Breno Leitao <leitao(a)debian.org> Signed-off-by: Al Viro <viro(a)zeniv.linux.org.uk> Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/configfs/dir.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 8c1a8d6a1861..c142e012573a 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -463,6 +463,9 @@ static struct dentry * configfs_lookup(struct inode *dir, inode = configfs_create(dentry, mode); if (IS_ERR(inode)) { + spin_lock(&configfs_dirent_lock); + sd->s_dentry = NULL; + spin_unlock(&configfs_dirent_lock); configfs_put(sd); return ERR_CAST(inode); } -- 2.52.0
2 1
0 0
[PATCH OLK-5.10] configfs: fix lockless traversals of ->s_children
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v7.2-rc1 commit 9b9e8bb81c41fd27e7b57a1c936fde140548535f category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18047 CVE: CVE-2026-74330 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- Having the parent directory locked protects entries from removal by another thread, but it does *not* protect cursors from being moved around by lseek() - or freed, for that matter. Fixes: 6f6107640625 ("configfs: Introduce configfs_dirent_lock") Reviewed-by: Jan Kara <jack(a)suse.cz> Signed-off-by: Al Viro <viro(a)zeniv.linux.org.uk> Conflicts: fs/configfs/dir.c [Context conflicts.] Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/configfs/dir.c | 54 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 8c1a8d6a1861..4913c1cecfb5 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -227,15 +227,16 @@ static int configfs_dirent_exists(struct configfs_dirent *parent_sd, { struct configfs_dirent * sd; + spin_lock(&configfs_dirent_lock); list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { if (sd->s_element) { - const unsigned char *existing = configfs_get_name(sd); - if (strcmp(existing, new)) - continue; - else + if (strcmp(configfs_get_name(sd), new) == 0) { + spin_unlock(&configfs_dirent_lock); return -EEXIST; + } } } + spin_unlock(&configfs_dirent_lock); return 0; } @@ -549,11 +550,28 @@ static void configfs_detach_rollback(struct dentry *dentry) configfs_detach_rollback(sd->s_dentry); } +/* + * Find the next non-cursor. configfs_dirent_lock held by caller. + */ +static struct configfs_dirent *next_dirent(struct configfs_dirent *parent, + struct configfs_dirent *last) +{ + struct configfs_dirent *s; + + s = list_prepare_entry(last, &parent->s_children, s_sibling); + + list_for_each_entry_continue(s, &parent->s_children, s_sibling) { + if (s->s_element) + return s; + } + return NULL; +} + static void detach_attrs(struct config_item * item) { struct dentry * dentry = dget(item->ci_dentry); - struct configfs_dirent * parent_sd; - struct configfs_dirent * sd, * tmp; + struct configfs_dirent *parent_sd; + struct configfs_dirent *sd, *next; if (!dentry) return; @@ -562,15 +580,19 @@ static void detach_attrs(struct config_item * item) dentry->d_name.name); parent_sd = dentry->d_fsdata; - list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { - if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED)) + + spin_lock(&configfs_dirent_lock); + for (sd = next_dirent(parent_sd, NULL); sd; sd = next) { + next = next_dirent(parent_sd, sd); + if (!(sd->s_type & CONFIGFS_NOT_PINNED)) continue; - spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); spin_unlock(&configfs_dirent_lock); configfs_drop_dentry(sd, dentry); configfs_put(sd); + spin_lock(&configfs_dirent_lock); } + spin_unlock(&configfs_dirent_lock); /** * Drop reference from dget() on entrance. @@ -619,18 +641,20 @@ static void detach_groups(struct config_group *group) struct dentry * dentry = dget(group->cg_item.ci_dentry); struct dentry *child; struct configfs_dirent *parent_sd; - struct configfs_dirent *sd, *tmp; + struct configfs_dirent *sd, *next; if (!dentry) return; parent_sd = dentry->d_fsdata; - list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { - if (!sd->s_element || - !(sd->s_type & CONFIGFS_USET_DEFAULT)) + spin_lock(&configfs_dirent_lock); + for (sd = next_dirent(parent_sd, NULL); sd; sd = next) { + next = next_dirent(parent_sd, sd); + if (!(sd->s_type & CONFIGFS_USET_DEFAULT)) continue; child = sd->s_dentry; + spin_unlock(&configfs_dirent_lock); inode_lock(d_inode(child)); @@ -642,7 +666,9 @@ static void detach_groups(struct config_group *group) d_delete(child); dput(child); + spin_lock(&configfs_dirent_lock); } + spin_unlock(&configfs_dirent_lock); /** * Drop reference from dget() on entrance. @@ -1094,6 +1120,7 @@ configfs_find_subsys_dentry(struct configfs_dirent *root_sd, struct configfs_dirent *p; struct configfs_dirent *ret = NULL; + spin_lock(&configfs_dirent_lock); list_for_each_entry(p, &root_sd->s_children, s_sibling) { if (p->s_type & CONFIGFS_DIR && p->s_element == subsys_item) { @@ -1101,6 +1128,7 @@ configfs_find_subsys_dentry(struct configfs_dirent *root_sd, break; } } + spin_unlock(&configfs_dirent_lock); return ret; } -- 2.52.0
2 1
0 0
[PATCH OLK-5.10 0/2] ovl: check access to copy_file_range source with src mounter creds
by Ran Hongyun 04 Sep '26

04 Sep '26
Export rw_verify_area and check access to copy_file_range source with src mounter creds. Patch 1 export rw_verify_area for verification. Patch 2 check access to copy_file_range source with src mounter creds Ran Hongyun (2): fs: export rw_verify_area() ovl: check access to copy_file_range source with src mounter creds fs/internal.h | 5 ----- fs/overlayfs/file.c | 17 +++++++++++++++++ fs/read_write.c | 1 + include/linux/fs.h | 1 + 4 files changed, 19 insertions(+), 5 deletions(-) -- 2.52.0
2 1
0 0
[PATCH OLK-6.6] ovl: check access to copy_file_range source with src mounter creds
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v7.2-rc5 commit a1e0eb8f55cfe09bb31a202a388babc411292656 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17160 CVE: CVE-2026-68448 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- Commit 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") allowed filesystems that implement the copy_file_range() f_op to decide if they want to access cross-sb copy from/to the same fs type. The same commit added checks to verify same sb copy for filesystems that implement ->copy_file_range() and do not support cross-sb copy at the time, namely, to ceph, fuse and nfs. The two remaining fs which implement ->copy_file_range(), cifs and overlayfs started to support cross-sb copy from this time. While overlayfs does support cross-sb copy when the two underlying files are on the same base fs, the copy operation on the two real files from two different overalyfs filesystems is performed with the mounter creds of the destination overlayfs and the read permission access hook for the source file was called with the wrong creds. This could cause either deny of access to copy which would otherwise be allowed (e.g. with splice) or allow read access to file which would otherwise be denied. Fix the latter case by explicitly verifying read access to source file with the source overlayfs mounter creds. The former case remains a quirk of cross-sb overlayfs copy, but userspace could fall back to regular copy so no harm done. Fixes: 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") Signed-off-by: Amir Goldstein <amir73il(a)gmail.com> Link: https://patch.msgid.link/20260712122421.203113-1-amir73il@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner(a)kernel.org> Conflicts: fs/overlayfs/file.c [6f5c84162a30 ("ovl: add override_creds cleanup guard extension for overlayfs") not merged.] Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/overlayfs/file.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index d11c104e6ef2..171979f7872b 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -487,6 +487,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t len, unsigned int flags, enum ovl_copyop op) { + struct inode *inode_in = file_inode(file_in); struct inode *inode_out = file_inode(file_out); struct fd real_in, real_out; const struct cred *old_cred; @@ -511,6 +512,22 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, goto out_unlock; } + /* + * For cross-sb copy, vfs_copy_file_range() will verify read access with + * the mounter creds of the dest fs mounter, so we need to explicitly + * verify read access with the source mounter creds. + */ + if (unlikely(inode_in->i_sb != inode_out->i_sb)) { + old_cred = ovl_override_creds(inode_in->i_sb); + ret = rw_verify_area(READ, real_in.file, &pos_in, len); + revert_creds(old_cred); + if (unlikely(ret)) { + fdput(real_in); + fdput(real_out); + goto out_unlock; + } + } + old_cred = ovl_override_creds(file_inode(file_out)->i_sb); switch (op) { case OVL_COPY: -- 2.52.0
2 1
0 0
[PATCH OLK-6.6] iomap: guard io_size EOF trim against concurrent truncate underflow
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v7.2-rc2 commit 55ec50d046c03b3724741957f7b007856e36dbe7 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17916 CVE: CVE-2026-72367 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- iomap: fix zero padding data issue in concurrent append writes changed ioend accounting so that io_size tracks only valid data within EOF. This trims io_size when a writeback range extends past end_pos: ioend->io_size += map_len; if (ioend->io_offset + ioend->io_size > end_pos) ioend->io_size = end_pos - ioend->io_offset; However, if end_pos ends up below ioend->io_offset, the subtraction becomes negative and is stored in size_t io_size, causing an unsigned wrap to a huge value. This can happen when writeback continues past byte-level EOF up to a block-aligned range, or when a concurrent truncate shrinks the file after end_pos was sampled in iomap_writeback_handle_eof(). A wrapped io_size can mislead append detection and corrupt completion-time size handling, since filesystem end_io paths consume io_size for decisions such as on-disk EOF updates and unwritten/COW completion ranges. Fix this by clamping io_size to zero when EOF has moved to or before the ioend start offset. This preserves the original intent of trimming io_size to valid in-EOF data while avoiding the underflow. Fixes: 51d20d1dacbe ("iomap: fix zero padding data issue in concurrent append writes") Suggested-by: Christoph Hellwig <hch(a)lst.de> Signed-off-by: Morduan Zang <zhangdandan(a)uniontech.com> Link: https://patch.msgid.link/9E38E2659B47DC2A+20260624062622.337469-1-zhangdand… Reviewed-by: Christoph Hellwig <hch(a)lst.de> Signed-off-by: Christian Brauner (Amutable) <brauner(a)kernel.org> Conflicts: fs/iomap/buffered-io.c [5fcbd555d483 ("iomap: split bios to zone append limits in the submission handlers") not merged.] Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/iomap/buffered-io.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 1b9177ad7cdd..baa7bbe02fad 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -2002,8 +2002,12 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, * should not be trimmed in such cases. */ wpc->ioend->io_size += len; - if (pos < isize && pos + len > isize) - wpc->ioend->io_size = isize - wpc->ioend->io_offset; + if (wpc->ioend->io_offset + wpc->ioend->io_size > isize) { + if (wpc->ioend->io_offset >= isize) + wpc->ioend->io_size = 0; + else + wpc->ioend->io_size = isize - wpc->ioend->io_offset; + } wbc_account_cgroup_owner(wbc, &folio->page, len); return 0; -- 2.52.0
2 1
0 0
[PATCH openEuler-1.0-LTS 2/2] ovl: check access to copy_file_range source with src mounter creds
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v7.2-rc5 commit a1e0eb8f55cfe09bb31a202a388babc411292656 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17160 CVE: CVE-2026-68448 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- Commit 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") allowed filesystems that implement the copy_file_range() f_op to decide if they want to access cross-sb copy from/to the same fs type. The same commit added checks to verify same sb copy for filesystems that implement ->copy_file_range() and do not support cross-sb copy at the time, namely, to ceph, fuse and nfs. The two remaining fs which implement ->copy_file_range(), cifs and overlayfs started to support cross-sb copy from this time. While overlayfs does support cross-sb copy when the two underlying files are on the same base fs, the copy operation on the two real files from two different overalyfs filesystems is performed with the mounter creds of the destination overlayfs and the read permission access hook for the source file was called with the wrong creds. This could cause either deny of access to copy which would otherwise be allowed (e.g. with splice) or allow read access to file which would otherwise be denied. Fix the latter case by explicitly verifying read access to source file with the source overlayfs mounter creds. The former case remains a quirk of cross-sb overlayfs copy, but userspace could fall back to regular copy so no harm done. Fixes: 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") Signed-off-by: Amir Goldstein <amir73il(a)gmail.com> Link: https://patch.msgid.link/20260712122421.203113-1-amir73il@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner(a)kernel.org> Conflicts: fs/overlayfs/file.c [6f5c84162a30 ("ovl: add override_creds cleanup guard extension for overlayfs") not merged.] Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/overlayfs/file.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 63b7b2600d81..4d9b73cc31ad 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -583,6 +583,7 @@ static ssize_t ovl_copyfile(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, u64 len, unsigned int flags, enum ovl_copyop op) { + struct inode *inode_in = file_inode(file_in); struct inode *inode_out = file_inode(file_out); struct fd real_in, real_out; const struct cred *old_cred; @@ -598,6 +599,22 @@ static ssize_t ovl_copyfile(struct file *file_in, loff_t pos_in, return ret; } + /* + * For cross-sb copy, vfs_copy_file_range() will verify read access with + * the mounter creds of the dest fs mounter, so we need to explicitly + * verify read access with the source mounter creds. + */ + if (unlikely(inode_in->i_sb != inode_out->i_sb)) { + old_cred = ovl_override_creds(inode_in->i_sb); + ret = rw_verify_area(READ, real_in.file, &pos_in, len); + revert_creds(old_cred); + if (unlikely(ret)) { + fdput(real_in); + fdput(real_out); + goto out_unlock; + } + } + old_cred = ovl_override_creds(file_inode(file_out)->i_sb); switch (op) { case OVL_COPY: -- 2.52.0
1 0
0 0
[PATCH openEuler-1.0-LTS 1/2] fs: export rw_verify_area()
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v5.18-rc1 commit 871129332d74c9e94bd110932ac4445833995639 category: cleanup bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17160 CVE: CVE-2026-68448 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- I'm adding btrfs ioctls to read and write compressed data, and rather than duplicating the checks in rw_verify_area(), let's just export it. Reviewed-by: Josef Bacik <josef(a)toxicpanda.com> Signed-off-by: Omar Sandoval <osandov(a)fb.com> Reviewed-by: David Sterba <dsterba(a)suse.com> Signed-off-by: David Sterba <dsterba(a)suse.com> Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/internal.h | 5 ---- fs/read_write.c | 1 + include/linux/fs.h | 1 + 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index a17f76e7651e..71db6ce61a77 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -151,11 +151,6 @@ extern int d_set_mounted(struct dentry *dentry); extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc); extern struct dentry *d_alloc_cursor(struct dentry *); -/* - * read_write.c - */ -extern int rw_verify_area(int, struct file *, const loff_t *, size_t); - /* * pipe.c */ diff --git a/fs/read_write.c b/fs/read_write.c index c90152064615..f026231f9e0b 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -393,6 +393,7 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t return security_file_permission(file, read_write == READ ? MAY_READ : MAY_WRITE); } +EXPORT_SYMBOL(rw_verify_area); static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 584957a75822..5714bea3bc3c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3135,6 +3135,7 @@ extern loff_t fixed_size_llseek(struct file *file, loff_t offset, int whence, loff_t size); extern loff_t no_seek_end_llseek_size(struct file *, loff_t, int, loff_t); extern loff_t no_seek_end_llseek(struct file *, loff_t, int); +int rw_verify_area(int, struct file *, const loff_t *, size_t); extern int generic_file_open(struct inode * inode, struct file * filp); extern int nonseekable_open(struct inode * inode, struct file * filp); extern int stream_open(struct inode * inode, struct file * filp); -- 2.52.0
1 0
0 0
[PATCH OLK-5.10 2/2] ovl: check access to copy_file_range source with src mounter creds
by Ran Hongyun 04 Sep '26

04 Sep '26
mainline inclusion from mainline-v7.2-rc5 commit a1e0eb8f55cfe09bb31a202a388babc411292656 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17160 CVE: CVE-2026-68448 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- Commit 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") allowed filesystems that implement the copy_file_range() f_op to decide if they want to access cross-sb copy from/to the same fs type. The same commit added checks to verify same sb copy for filesystems that implement ->copy_file_range() and do not support cross-sb copy at the time, namely, to ceph, fuse and nfs. The two remaining fs which implement ->copy_file_range(), cifs and overlayfs started to support cross-sb copy from this time. While overlayfs does support cross-sb copy when the two underlying files are on the same base fs, the copy operation on the two real files from two different overalyfs filesystems is performed with the mounter creds of the destination overlayfs and the read permission access hook for the source file was called with the wrong creds. This could cause either deny of access to copy which would otherwise be allowed (e.g. with splice) or allow read access to file which would otherwise be denied. Fix the latter case by explicitly verifying read access to source file with the source overlayfs mounter creds. The former case remains a quirk of cross-sb overlayfs copy, but userspace could fall back to regular copy so no harm done. Fixes: 5dae222a5ff0c ("vfs: allow copy_file_range to copy across devices") Signed-off-by: Amir Goldstein <amir73il(a)gmail.com> Link: https://patch.msgid.link/20260712122421.203113-1-amir73il@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner(a)kernel.org> Conflicts: fs/overlayfs/file.c [6f5c84162a30 ("ovl: add override_creds cleanup guard extension for overlayfs") not merged.] Signed-off-by: Ran Hongyun <ranhongyun1(a)huawei.com> --- fs/overlayfs/file.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 02427e6fdfb0..09651572e633 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -696,6 +696,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t len, unsigned int flags, enum ovl_copyop op) { + struct inode *inode_in = file_inode(file_in); struct inode *inode_out = file_inode(file_out); struct fd real_in, real_out; const struct cred *old_cred; @@ -720,6 +721,22 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, goto out_unlock; } + /* + * For cross-sb copy, vfs_copy_file_range() will verify read access with + * the mounter creds of the dest fs mounter, so we need to explicitly + * verify read access with the source mounter creds. + */ + if (unlikely(inode_in->i_sb != inode_out->i_sb)) { + old_cred = ovl_override_creds(inode_in->i_sb); + ret = rw_verify_area(READ, real_in.file, &pos_in, len); + revert_creds(old_cred); + if (unlikely(ret)) { + fdput(real_in); + fdput(real_out); + goto out_unlock; + } + } + old_cred = ovl_override_creds(file_inode(file_out)->i_sb); switch (op) { case OVL_COPY: -- 2.52.0
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • ...
  • 2487
  • Older →

HyperKitty Powered by HyperKitty