Skip to content

Commit 4a8521b

Browse files
author
Kent Overstreet
committed
bcachefs: Inodes need extra padding for varint_decode_fast()
Reported-by: syzbot+66b9b74f6520068596a9@syzkaller.appspotmail.com Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent b30b70a commit 4a8521b

1 file changed

Lines changed: 18 additions & 10 deletions

File tree

fs/bcachefs/io_write.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,6 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
199199
u64 new_i_size,
200200
s64 i_sectors_delta)
201201
{
202-
struct btree_iter iter;
203-
struct bkey_i *k;
204-
struct bkey_i_inode_v3 *inode;
205202
/*
206203
* Crazy performance optimization:
207204
* Every extent update needs to also update the inode: the inode trigger
@@ -214,25 +211,36 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
214211
* lost, but that's fine.
215212
*/
216213
unsigned inode_update_flags = BTREE_UPDATE_NOJOURNAL;
217-
int ret;
218214

219-
k = bch2_bkey_get_mut_noupdate(trans, &iter, BTREE_ID_inodes,
215+
struct btree_iter iter;
216+
struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
220217
SPOS(0,
221218
extent_iter->pos.inode,
222219
extent_iter->snapshot),
223220
BTREE_ITER_CACHED);
224-
ret = PTR_ERR_OR_ZERO(k);
221+
int ret = bkey_err(k);
225222
if (unlikely(ret))
226223
return ret;
227224

228-
if (unlikely(k->k.type != KEY_TYPE_inode_v3)) {
229-
k = bch2_inode_to_v3(trans, k);
230-
ret = PTR_ERR_OR_ZERO(k);
225+
/*
226+
* varint_decode_fast(), in the inode .invalid method, reads up to 7
227+
* bytes past the end of the buffer:
228+
*/
229+
struct bkey_i *k_mut = bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k) + 8);
230+
ret = PTR_ERR_OR_ZERO(k_mut);
231+
if (unlikely(ret))
232+
goto err;
233+
234+
bkey_reassemble(k_mut, k);
235+
236+
if (unlikely(k_mut->k.type != KEY_TYPE_inode_v3)) {
237+
k_mut = bch2_inode_to_v3(trans, k_mut);
238+
ret = PTR_ERR_OR_ZERO(k_mut);
231239
if (unlikely(ret))
232240
goto err;
233241
}
234242

235-
inode = bkey_i_to_inode_v3(k);
243+
struct bkey_i_inode_v3 *inode = bkey_i_to_inode_v3(k_mut);
236244

237245
if (!(le64_to_cpu(inode->v.bi_flags) & BCH_INODE_i_size_dirty) &&
238246
new_i_size > le64_to_cpu(inode->v.bi_size)) {

0 commit comments

Comments
 (0)