From ab2a1cb5712bd146550977cd63ec3bbbc34095a7 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 1 May 2024 15:23:10 -0500 Subject: [PATCH] Enabled erase=noop in test_rbyd, changed read* to error on leb128 overflow Now that reproducibility issues with erase_value=-1 (erase=noop) are fixed, this much more useful to test than erase_value=0x1b. Especially since erase=noop is filled with so many sharp corners. These tests already found that we were being too confident with our leb128/lleb128/tag parsing. Since we need to partially parse unfinished/ old commits, lfsr_dir_read* can easily encounter invalid leb128s during normal operation. If this happens we should not assert. Doing things correctly has a bit of a cost: code stack before: 33928 2824 after: 33976 (+0.1%) 2824 (+0.0%) At least we haven't seen any issues with our valid bit invalidating logic yet. --- lfs.c | 18 +++++++++++++----- tests/test_rbyd.toml | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lfs.c b/lfs.c index 5375da1f..40dc1de4 100644 --- a/lfs.c +++ b/lfs.c @@ -1075,7 +1075,9 @@ static lfs_ssize_t lfsr_bd_readtag_(lfs_t *lfs, return d_; } // weights should be limited to 31-bits - LFS_ASSERT(weight <= 0x7fffffff); + if (weight > 0x7fffffff) { + return LFS_ERR_CORRUPT; + } d += d_; lfs_size_t size; @@ -1084,7 +1086,9 @@ static lfs_ssize_t lfsr_bd_readtag_(lfs_t *lfs, return d_; } // sizes should be limited to 28-bits - LFS_ASSERT(size <= 0x0fffffff); + if (size > 0x0fffffff) { + return LFS_ERR_CORRUPT; + } d += d_; // optional checksum @@ -1405,7 +1409,9 @@ static int lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t *data, return d; } // all leb128s in our system reserve the sign bit - LFS_ASSERT(*word_ <= 0x7fffffff); + if (*word_ > 0x7fffffff) { + return LFS_ERR_CORRUPT; + } *data = lfsr_data_slice(*data, d, -1); return 0; @@ -1422,9 +1428,11 @@ static inline int lfsr_data_readlleb128(lfs_t *lfs, lfsr_data_t *data, if (err) { return err; } - // little-leb128s should be limited to 28-bits - LFS_ASSERT(*word_ <= 0x0fffffff); + if (*word_ > 0x0fffffff) { + return LFS_ERR_CORRUPT; + } + return 0; } diff --git a/tests/test_rbyd.toml b/tests/test_rbyd.toml index cd308d98..3af13ddc 100644 --- a/tests/test_rbyd.toml +++ b/tests/test_rbyd.toml @@ -2,7 +2,7 @@ after = 'test_bd' # test with a number of different erase values -defines.ERASE_VALUE = [0xff, 0x00, 0x1b] +defines.ERASE_VALUE = [0xff, 0x00, -1] # set block_size to the full size of disk so we can test arbitrarily # large rbyd trees, we don't really care about block sizes at this