Skip to content

Commit 031ad9e

Browse files
author
Kent Overstreet
committed
bcachefs: Check for packed bkeys that are too big
add missing validation; fixes assertion pop in bkey unpack Signed-off-by: Kent Overstreet <[email protected]>
1 parent 58caa78 commit 031ad9e

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

fs/bcachefs/bkey.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,12 @@ static inline unsigned bkeyp_key_u64s(const struct bkey_format *format,
314314
return bkey_packed(k) ? format->key_u64s : BKEY_U64s;
315315
}
316316

317+
static inline bool bkeyp_u64s_valid(const struct bkey_format *f,
318+
const struct bkey_packed *k)
319+
{
320+
return ((unsigned) k->u64s - bkeyp_key_u64s(f, k) <= U8_MAX - BKEY_U64s);
321+
}
322+
317323
static inline unsigned bkeyp_key_bytes(const struct bkey_format *format,
318324
const struct bkey_packed *k)
319325
{

fs/bcachefs/btree_io.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ static int bset_key_invalid(struct bch_fs *c, struct btree *b,
831831
(rw == WRITE ? bch2_bkey_val_invalid(c, k, READ, err) : 0);
832832
}
833833

834-
static bool __bkey_valid(struct bch_fs *c, struct btree *b,
834+
static bool bkey_packed_valid(struct bch_fs *c, struct btree *b,
835835
struct bset *i, struct bkey_packed *k)
836836
{
837837
if (bkey_p_next(k) > vstruct_last(i))
@@ -840,7 +840,7 @@ static bool __bkey_valid(struct bch_fs *c, struct btree *b,
840840
if (k->format > KEY_FORMAT_CURRENT)
841841
return false;
842842

843-
if (k->u64s < bkeyp_key_u64s(&b->format, k))
843+
if (!bkeyp_u64s_valid(&b->format, k))
844844
return false;
845845

846846
struct printbuf buf = PRINTBUF;
@@ -884,11 +884,13 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
884884
"invalid bkey format %u", k->format))
885885
goto drop_this_key;
886886

887-
if (btree_err_on(k->u64s < bkeyp_key_u64s(&b->format, k),
887+
if (btree_err_on(!bkeyp_u64s_valid(&b->format, k),
888888
-BCH_ERR_btree_node_read_err_fixable,
889889
c, NULL, b, i,
890890
btree_node_bkey_bad_u64s,
891-
"k->u64s too small (%u < %u)", k->u64s, bkeyp_key_u64s(&b->format, k)))
891+
"bad k->u64s %u (min %u max %lu)", k->u64s,
892+
bkeyp_key_u64s(&b->format, k),
893+
U8_MAX - BKEY_U64s + bkeyp_key_u64s(&b->format, k)))
892894
goto drop_this_key;
893895

894896
if (!write)
@@ -947,13 +949,12 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
947949
* do
948950
*/
949951

950-
if (!__bkey_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) {
952+
if (!bkey_packed_valid(c, b, i, (void *) ((u64 *) k + next_good_key))) {
951953
for (next_good_key = 1;
952954
next_good_key < (u64 *) vstruct_last(i) - (u64 *) k;
953955
next_good_key++)
954-
if (__bkey_valid(c, b, i, (void *) ((u64 *) k + next_good_key)))
956+
if (bkey_packed_valid(c, b, i, (void *) ((u64 *) k + next_good_key)))
955957
goto got_good_key;
956-
957958
}
958959

959960
/*

0 commit comments

Comments
 (0)