[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <202510020639.uRHSs90S-lkp@intel.com>
Date: Thu, 2 Oct 2025 07:11:53 +0800
From: kernel test robot <lkp@...el.com>
To: syzbot <syzbot+9db318d6167044609878@...kaller.appspotmail.com>,
linux-kernel@...r.kernel.org, syzkaller-bugs@...glegroups.com
Cc: oe-kbuild-all@...ts.linux.dev
Subject: Re: Forwarded: [PATCH] ext4: fix use-after-free in
ext4_ext_insert_extent()
Hi syzbot,
kernel test robot noticed the following build warnings:
[auto build test WARNING on tytso-ext4/dev]
[also build test WARNING on linus/master v6.17 next-20250929]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/syzbot/Forwarded-PATCH-ext4-fix-use-after-free-in-ext4_ext_insert_extent/20250930-232453
base: https://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
patch link: https://lore.kernel.org/r/68dbf53f.a00a0220.102ee.004a.GAE%40google.com
patch subject: Forwarded: [PATCH] ext4: fix use-after-free in ext4_ext_insert_extent()
config: arc-randconfig-r073-20251001 (https://download.01.org/0day-ci/archive/20251002/202510020639.uRHSs90S-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 13.4.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@...el.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510020639.uRHSs90S-lkp@intel.com/
New smatch warnings:
fs/ext4/extents.c:2089 ext4_ext_insert_extent() warn: inconsistent indenting
Old smatch warnings:
arch/arc/include/asm/thread_info.h:62 current_thread_info() error: uninitialized symbol 'sp'.
fs/ext4/extents.c:4456 ext4_ext_map_blocks() error: uninitialized symbol 'ex'.
fs/ext4/extents.c:4456 ext4_ext_map_blocks() error: uninitialized symbol 'depth'.
vim +2089 fs/ext4/extents.c
1969
1970 /*
1971 * ext4_ext_insert_extent:
1972 * tries to merge requested extent into the existing extent or
1973 * inserts requested extent as new one into the tree,
1974 * creating new leaf in the no-space case.
1975 */
1976 struct ext4_ext_path *
1977 ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1978 struct ext4_ext_path *path,
1979 struct ext4_extent *newext, int gb_flags)
1980 {
1981 struct ext4_extent_header *eh;
1982 struct ext4_extent *ex, *fex;
1983 struct ext4_extent *nearex; /* nearest extent */
1984 int depth, len, err = 0;
1985 ext4_lblk_t next;
1986 int mb_flags = 0, unwritten;
1987
1988 if (gb_flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
1989 mb_flags |= EXT4_MB_DELALLOC_RESERVED;
1990 if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
1991 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
1992 err = -EFSCORRUPTED;
1993 goto errout;
1994 }
1995 depth = ext_depth(inode);
1996 ex = path[depth].p_ext;
1997 eh = path[depth].p_hdr;
1998 if (unlikely(path[depth].p_hdr == NULL)) {
1999 EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
2000 err = -EFSCORRUPTED;
2001 goto errout;
2002 }
2003
2004 /* try to insert block into found extent and return */
2005 if (ex && !(gb_flags & EXT4_GET_BLOCKS_PRE_IO)) {
2006
2007 /*
2008 * Try to see whether we should rather test the extent on
2009 * right from ex, or from the left of ex. This is because
2010 * ext4_find_extent() can return either extent on the
2011 * left, or on the right from the searched position. This
2012 * will make merging more effective.
2013 */
2014 if (ex < EXT_LAST_EXTENT(eh) &&
2015 (le32_to_cpu(ex->ee_block) +
2016 ext4_ext_get_actual_len(ex) <
2017 le32_to_cpu(newext->ee_block))) {
2018 ex += 1;
2019 goto prepend;
2020 } else if ((ex > EXT_FIRST_EXTENT(eh)) &&
2021 (le32_to_cpu(newext->ee_block) +
2022 ext4_ext_get_actual_len(newext) <
2023 le32_to_cpu(ex->ee_block)))
2024 ex -= 1;
2025
2026 /* Try to append newex to the ex */
2027 if (ext4_can_extents_be_merged(inode, ex, newext)) {
2028 ext_debug(inode, "append [%d]%d block to %u:[%d]%d"
2029 "(from %llu)\n",
2030 ext4_ext_is_unwritten(newext),
2031 ext4_ext_get_actual_len(newext),
2032 le32_to_cpu(ex->ee_block),
2033 ext4_ext_is_unwritten(ex),
2034 ext4_ext_get_actual_len(ex),
2035 ext4_ext_pblock(ex));
2036 err = ext4_ext_get_access(handle, inode,
2037 path + depth);
2038 if (err)
2039 goto errout;
2040 unwritten = ext4_ext_is_unwritten(ex);
2041 ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)
2042 + ext4_ext_get_actual_len(newext));
2043 if (unwritten)
2044 ext4_ext_mark_unwritten(ex);
2045 nearex = ex;
2046 goto merge;
2047 }
2048
2049 prepend:
2050 /* Try to prepend newex to the ex */
2051 if (ext4_can_extents_be_merged(inode, newext, ex)) {
2052 ext_debug(inode, "prepend %u[%d]%d block to %u:[%d]%d"
2053 "(from %llu)\n",
2054 le32_to_cpu(newext->ee_block),
2055 ext4_ext_is_unwritten(newext),
2056 ext4_ext_get_actual_len(newext),
2057 le32_to_cpu(ex->ee_block),
2058 ext4_ext_is_unwritten(ex),
2059 ext4_ext_get_actual_len(ex),
2060 ext4_ext_pblock(ex));
2061 err = ext4_ext_get_access(handle, inode,
2062 path + depth);
2063 if (err)
2064 goto errout;
2065
2066 unwritten = ext4_ext_is_unwritten(ex);
2067 ex->ee_block = newext->ee_block;
2068 ext4_ext_store_pblock(ex, ext4_ext_pblock(newext));
2069 ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)
2070 + ext4_ext_get_actual_len(newext));
2071 if (unwritten)
2072 ext4_ext_mark_unwritten(ex);
2073 nearex = ex;
2074 goto merge;
2075 }
2076 }
2077
2078 depth = ext_depth(inode);
2079 eh = path[depth].p_hdr;
2080 if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max))
2081 goto has_space;
2082
2083 /* probably next leaf has space for us? */
2084 fex = EXT_LAST_EXTENT(eh);
2085 next = EXT_MAX_BLOCKS;
2086 if (le16_to_cpu(eh->eh_magic) != EXT4_EXT_MAGIC ||
2087 le16_to_cpu(eh->eh_entries) == 0) {
2088 EXT4_ERROR_INODE(inode, "corrupted extent header");
> 2089 err = -EFSCORRUPTED;
2090 goto errout;
2091 }
2092 if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block))
2093 next = ext4_ext_next_leaf_block(path);
2094 if (next != EXT_MAX_BLOCKS) {
2095 struct ext4_ext_path *npath;
2096
2097 ext_debug(inode, "next leaf block - %u\n", next);
2098 npath = ext4_find_extent(inode, next, NULL, gb_flags);
2099 if (IS_ERR(npath)) {
2100 err = PTR_ERR(npath);
2101 goto errout;
2102 }
2103 BUG_ON(npath->p_depth != path->p_depth);
2104 eh = npath[depth].p_hdr;
2105 if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max)) {
2106 ext_debug(inode, "next leaf isn't full(%d)\n",
2107 le16_to_cpu(eh->eh_entries));
2108 ext4_free_ext_path(path);
2109 path = npath;
2110 goto has_space;
2111 }
2112 ext_debug(inode, "next leaf has no free space(%d,%d)\n",
2113 le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max));
2114 ext4_free_ext_path(npath);
2115 }
2116
2117 /*
2118 * There is no free space in the found leaf.
2119 * We're gonna add a new leaf in the tree.
2120 */
2121 if (gb_flags & EXT4_GET_BLOCKS_METADATA_NOFAIL)
2122 mb_flags |= EXT4_MB_USE_RESERVED;
2123 path = ext4_ext_create_new_leaf(handle, inode, mb_flags, gb_flags,
2124 path, newext);
2125 if (IS_ERR(path))
2126 return path;
2127 depth = ext_depth(inode);
2128 eh = path[depth].p_hdr;
2129
2130 has_space:
2131 nearex = path[depth].p_ext;
2132
2133 err = ext4_ext_get_access(handle, inode, path + depth);
2134 if (err)
2135 goto errout;
2136
2137 if (!nearex) {
2138 /* there is no extent in this leaf, create first one */
2139 ext_debug(inode, "first extent in the leaf: %u:%llu:[%d]%d\n",
2140 le32_to_cpu(newext->ee_block),
2141 ext4_ext_pblock(newext),
2142 ext4_ext_is_unwritten(newext),
2143 ext4_ext_get_actual_len(newext));
2144 nearex = EXT_FIRST_EXTENT(eh);
2145 } else {
2146 if (le32_to_cpu(newext->ee_block)
2147 > le32_to_cpu(nearex->ee_block)) {
2148 /* Insert after */
2149 ext_debug(inode, "insert %u:%llu:[%d]%d before: "
2150 "nearest %p\n",
2151 le32_to_cpu(newext->ee_block),
2152 ext4_ext_pblock(newext),
2153 ext4_ext_is_unwritten(newext),
2154 ext4_ext_get_actual_len(newext),
2155 nearex);
2156 nearex++;
2157 } else {
2158 /* Insert before */
2159 BUG_ON(newext->ee_block == nearex->ee_block);
2160 ext_debug(inode, "insert %u:%llu:[%d]%d after: "
2161 "nearest %p\n",
2162 le32_to_cpu(newext->ee_block),
2163 ext4_ext_pblock(newext),
2164 ext4_ext_is_unwritten(newext),
2165 ext4_ext_get_actual_len(newext),
2166 nearex);
2167 }
2168 len = EXT_LAST_EXTENT(eh) - nearex + 1;
2169 if (len > 0) {
2170 ext_debug(inode, "insert %u:%llu:[%d]%d: "
2171 "move %d extents from 0x%p to 0x%p\n",
2172 le32_to_cpu(newext->ee_block),
2173 ext4_ext_pblock(newext),
2174 ext4_ext_is_unwritten(newext),
2175 ext4_ext_get_actual_len(newext),
2176 len, nearex, nearex + 1);
2177 memmove(nearex + 1, nearex,
2178 len * sizeof(struct ext4_extent));
2179 }
2180 }
2181
2182 le16_add_cpu(&eh->eh_entries, 1);
2183 path[depth].p_ext = nearex;
2184 nearex->ee_block = newext->ee_block;
2185 ext4_ext_store_pblock(nearex, ext4_ext_pblock(newext));
2186 nearex->ee_len = newext->ee_len;
2187
2188 merge:
2189 /* try to merge extents */
2190 if (!(gb_flags & EXT4_GET_BLOCKS_PRE_IO))
2191 ext4_ext_try_to_merge(handle, inode, path, nearex);
2192
2193 /* time to correct all indexes above */
2194 err = ext4_ext_correct_indexes(handle, inode, path);
2195 if (err)
2196 goto errout;
2197
2198 err = ext4_ext_dirty(handle, inode, path + path->p_depth);
2199 if (err)
2200 goto errout;
2201
2202 return path;
2203
2204 errout:
2205 ext4_free_ext_path(path);
2206 return ERR_PTR(err);
2207 }
2208
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Powered by blists - more mailing lists