summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-04-24 07:42:02 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:02 +0300
commitbc2e5d5c6636f6a5794e4ed306fb008b02e6f419 (patch)
treea753121a684ece4617ec43613a1c5721f8389751
parent65c0601a329580f6a016298f7148305288b7d719 (diff)
downloadlinux-bc2e5d5c6636f6a5794e4ed306fb008b02e6f419.tar.xz
bcachefs: Fix an out of bounds read
bch2_varint_decode() can read up to 7 bytes past the end of the buffer, which means we need to allocate slightly larger key cache buffers. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/btree_key_cache.c10
-rw-r--r--fs/bcachefs/btree_update_leaf.c6
2 files changed, 14 insertions, 2 deletions
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c
index 0716c3314a36..019d4d164553 100644
--- a/fs/bcachefs/btree_key_cache.c
+++ b/fs/bcachefs/btree_key_cache.c
@@ -219,8 +219,14 @@ static int btree_key_cache_fill(struct btree_trans *trans,
goto err;
}
- if (k.k->u64s > ck->u64s) {
- new_u64s = roundup_pow_of_two(k.k->u64s);
+ /*
+ * bch2_varint_decode can read past the end of the buffer by at
+ * most 7 bytes (it won't be used):
+ */
+ new_u64s = k.k->u64s + 1;
+
+ if (new_u64s > ck->u64s) {
+ new_u64s = roundup_pow_of_two(new_u64s);
new_k = kmalloc(new_u64s * sizeof(u64), GFP_NOFS);
if (!new_k) {
ret = -ENOMEM;
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 96b53effded7..e537bd64e1fb 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -293,6 +293,12 @@ btree_key_can_insert_cached(struct btree_trans *trans,
!(trans->flags & BTREE_INSERT_JOURNAL_RECLAIM))
return BTREE_INSERT_NEED_JOURNAL_RECLAIM;
+ /*
+ * bch2_varint_decode can read past the end of the buffer by at most 7
+ * bytes (it won't be used):
+ */
+ u64s += 1;
+
if (u64s <= ck->u64s)
return BTREE_INSERT_OK;