Message ID | 20250213191642.720812-1-kovalev@altlinux.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | ocfs2: validate l_tree_depth to avoid out-of-bounds access | expand |
On 2025/2/14 03:16, Vasiliy Kovalev wrote: > The l_tree_depth field in struct ocfs2_extent_list is defined > as __le16, but according to the comments in the structure > definition, the high 8 bits must not be used, meaning its > maximum valid value is 255. > > Add a check to prevent out-of-bounds access if l_tree_depth > has an invalid value, which may occur when reading from a > corrupted mounted disk [1]. > > Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem") > Reported-by: syzbot+66c146268dc88f4341fd@syzkaller.appspotmail.com > Closes: https://syzkaller.appspot.com/bug?extid=66c146268dc88f4341fd [1] > Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org> > --- > fs/ocfs2/extent_map.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > > diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c > index 930150ed5db15..0d9c25fdec029 100644 > --- a/fs/ocfs2/extent_map.c > +++ b/fs/ocfs2/extent_map.c > @@ -415,6 +415,15 @@ static int ocfs2_get_clusters_nocache(struct inode *inode, > tree_height = le16_to_cpu(el->l_tree_depth); > > if (tree_height > 0) { > + if (unlikely(tree_height > 255)) { In fact we won't allow larger tree depth. IIRC, it is OCFS2_MAX_PATH_DEPTH, refer ocfs2_new_path(). BTW, I'd like add this check in __ocfs2_find_path() instead. > + ocfs2_error(inode->i_sb, > + "Inode %lu has too large l_tree_depth=%u in leaf block %llu\n", It's not leaf, but root. Thanks, Joseph > + inode->i_ino, tree_height, > + (unsigned long long)di_bh->b_blocknr); > + ret = -EROFS; > + goto out; > + } > + > ret = ocfs2_find_leaf(INODE_CACHE(inode), el, v_cluster, > &eb_bh); > if (ret) {
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 930150ed5db15..0d9c25fdec029 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -415,6 +415,15 @@ static int ocfs2_get_clusters_nocache(struct inode *inode, tree_height = le16_to_cpu(el->l_tree_depth); if (tree_height > 0) { + if (unlikely(tree_height > 255)) { + ocfs2_error(inode->i_sb, + "Inode %lu has too large l_tree_depth=%u in leaf block %llu\n", + inode->i_ino, tree_height, + (unsigned long long)di_bh->b_blocknr); + ret = -EROFS; + goto out; + } + ret = ocfs2_find_leaf(INODE_CACHE(inode), el, v_cluster, &eb_bh); if (ret) {
The l_tree_depth field in struct ocfs2_extent_list is defined as __le16, but according to the comments in the structure definition, the high 8 bits must not be used, meaning its maximum valid value is 255. Add a check to prevent out-of-bounds access if l_tree_depth has an invalid value, which may occur when reading from a corrupted mounted disk [1]. Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem") Reported-by: syzbot+66c146268dc88f4341fd@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=66c146268dc88f4341fd [1] Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org> --- fs/ocfs2/extent_map.c | 9 +++++++++ 1 file changed, 9 insertions(+)