fix(bitscrambler): validate and safely load LUT data

Reject LUT loads that exceed the hardware address space and assemble
each 32-bit LUT word via memcpy so unaligned and partial inputs do not
read past the caller buffer. Add regression tests for oversized and
partial unaligned LUT loads.
This commit is contained in:
morris
2026-07-28 16:26:49 +08:00
parent 137fa05c7c
commit c3a707d996
3 changed files with 67 additions and 2 deletions
@@ -5,6 +5,7 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "sdkconfig.h"
#include "unity.h"
#include "unity_test_utils.h"
@@ -171,6 +172,51 @@ TEST_CASE("BitScrambler with LUT32", "[bs]")
free(data_out);
}
TEST_CASE("BitScrambler loads partial LUT from unaligned buffer", "[bs]")
{
const size_t len = 32;
const uint32_t expected_lut_words[] = {
0xA0011111,
0xA0022222,
0xA0033333,
0x00000044,
};
const uint32_t lut_source_words[] = {
0xA0011111,
0xA0022222,
0xA0033333,
0xA0044444,
};
uint8_t lut_bytes[sizeof(lut_source_words) + 4] = {0};
uint8_t *unaligned_lut = lut_bytes + 1;
const size_t lut_size = 13;
uint8_t *data_in = heap_caps_aligned_calloc(8, 1, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
uint32_t *data_out = heap_caps_aligned_calloc(8, 1, len * 4, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
TEST_ASSERT_NOT_NULL(data_in);
TEST_ASSERT_NOT_NULL(data_out);
memcpy(unaligned_lut, lut_source_words, sizeof(lut_source_words));
unaligned_lut[lut_size] = 0xAB;
unaligned_lut[lut_size + 1] = 0xCD;
unaligned_lut[lut_size + 2] = 0xEF;
bitscrambler_handle_t bs;
TEST_ESP_OK(bitscrambler_loopback_create(&bs, SOC_BITSCRAMBLER_ATTACH_GPSPI2, len * 4));
TEST_ESP_OK(bitscrambler_load_program(bs, bitscrambler_program_lut32));
TEST_ESP_OK(bitscrambler_load_lut(bs, unaligned_lut, lut_size));
size_t res_len = 0;
TEST_ESP_OK(bitscrambler_loopback_run(bs, data_in, len, data_out, len * 4, &res_len));
bitscrambler_free(bs);
for (size_t i = 0; i < res_len / 4; i++) {
TEST_ASSERT_EQUAL(expected_lut_words[i % 4], data_out[i]);
}
TEST_ASSERT_EQUAL(len * 4, res_len);
free(data_in);
free(data_out);
}
TEST_CASE("BitScrambler with loop instruction", "[bs]")
{
uint8_t data_in[] = {0x00, 0xFF, 0x55};