diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c index 1bf2a6593dec..15f3a711ea0a 100644 --- a/fs/ntfs3/index.c +++ b/fs/ntfs3/index.c @@ -478,6 +478,7 @@ static int indx_find_free(struct ntfs_index *indx, struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le = NULL; const struct INDEX_NAMES *in = &s_index_names[indx->type]; int err; + u64 bm_size; b = ni_find_attr(ni, NULL, &le, ATTR_BITMAP, in->name, in->name_len, NULL, NULL); @@ -488,6 +489,17 @@ static int indx_find_free(struct ntfs_index *indx, struct ntfs_inode *ni, *bitmap = b; *bit = MINUS_ONE_T; + bm_size = b->non_res ? le64_to_cpu(b->nres.valid_size) : + le32_to_cpu(b->res.data_size); + + /* + * Allocated index blocks require $BITMAP to contain at least + * one bit for usage tracking. A zero-length bitmap in this + * case indicates a malformed on-disk structure and cannot be used. + */ + if (unlikely(bm_size == 0 && indx->alloc_run.count)) + return -EINVAL; + if (!b->non_res) { u32 nbits = 8 * le32_to_cpu(b->res.data_size); size_t pos = find_next_zero_bit_le(resident_data(b), nbits, 0);