Skip to content

Commit b71db49

Browse files
author
Offir Kochalsky
committed
Prevent sector-unaligned erase
1 parent 1eab072 commit b71db49

File tree

3 files changed

+49
-53
lines changed

3 files changed

+49
-53
lines changed

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,22 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
339339
int size = (int)in_size;
340340
bool erase_failed = false;
341341
int status = SPIF_BD_ERROR_OK;
342-
// Find region of erased address
342+
// Find region of erased address
343343
int region = _utils_find_addr_region(addr);
344344
// Erase Types of selected region
345345
uint8_t bitfield = _region_erase_types_bitfield[region];
346346

347-
tr_error("DEBUG: erase - addr: %llu, in_size: %llu", addr, in_size);
347+
tr_info("DEBUG: erase - addr: %llu, in_size: %llu", addr, in_size);
348+
349+
if ((addr + in_size) > _device_size_bytes) {
350+
tr_error("ERROR: erase exceeds flash device size");
351+
return SPIF_BD_ERROR_INVALID_ERASE_PARAMS;
352+
}
353+
354+
if ( ((addr % get_erase_size(addr)) != 0 ) || (((addr + in_size) % get_erase_size(addr + in_size - 1)) != 0 ) ) {
355+
tr_error("ERROR: invalid erase - unaligned address and size");
356+
return SPIF_BD_ERROR_INVALID_ERASE_PARAMS;
357+
}
348358

349359
// For each iteration erase the largest section supported by current region
350360
while (size > 0) {
@@ -353,13 +363,12 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
353363
// find the matching instruction and erase size chunk for that type.
354364
type = _utils_iterate_next_largest_erase_type(bitfield, size, (unsigned int)addr, _region_high_boundary[region]);
355365
cur_erase_inst = _erase_type_inst_arr[type];
356-
//chunk = _erase_type_size_arr[type];
357366
offset = addr % _erase_type_size_arr[type];
358367
chunk = ( (offset + size) < _erase_type_size_arr[type]) ? size : (_erase_type_size_arr[type] - offset);
359368

360-
tr_error("DEBUG: erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %lu , ",
369+
tr_debug("DEBUG: erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %lu , ",
361370
addr, size, cur_erase_inst, chunk);
362-
tr_error("DEBUG: erase - Region: %d, Type:%d",
371+
tr_debug("DEBUG: erase - Region: %d, Type:%d",
363372
region, type);
364373

365374
_mutex->lock();

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
* @enum spif_bd_error
2626
*/
2727
enum spif_bd_error {
28-
SPIF_BD_ERROR_OK = 0, /*!< no error */
29-
SPIF_BD_ERROR_DEVICE_ERROR = BD_ERROR_DEVICE_ERROR, /*!< device specific error -4001 */
30-
SPIF_BD_ERROR_PARSING_FAILED = -4002, /* SFDP Parsing failed */
31-
SPIF_BD_ERROR_READY_FAILED = -4003, /* Wait for Mem Ready failed */
32-
SPIF_BD_ERROR_WREN_FAILED = -4004, /* Write Enable Failed */
28+
SPIF_BD_ERROR_OK = 0, /*!< no error */
29+
SPIF_BD_ERROR_DEVICE_ERROR = BD_ERROR_DEVICE_ERROR, /*!< device specific error -4001 */
30+
SPIF_BD_ERROR_PARSING_FAILED = -4002, /* SFDP Parsing failed */
31+
SPIF_BD_ERROR_READY_FAILED = -4003, /* Wait for Mem Ready failed */
32+
SPIF_BD_ERROR_WREN_FAILED = -4004, /* Write Enable Failed */
33+
SPIF_BD_ERROR_INVALID_ERASE_PARAMS = -4005, /* Erase command not on sector aligned addresses or exceeds device size */
3334
};
3435

3536

@@ -136,6 +137,7 @@ class SPIFBlockDevice : public BlockDevice {
136137
* SPIF_BD_ERROR_DEVICE_ERROR - device driver transaction failed
137138
* SPIF_BD_ERROR_READY_FAILED - Waiting for Memory ready failed or timed out
138139
* SPIF_BD_ERROR_WREN_FAILED - Write Enable failed
140+
* SPIF_BD_ERROR_INVALID_ERASE_PARAMS - Trying to erase unaligned address or size
139141
*/
140142
virtual int erase(bd_addr_t addr, bd_size_t size);
141143

components/storage/blockdevice/COMPONENT_SPIF/TESTS/block_device/spif/main.cpp

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ void test_spif_random_program_read_erase()
131131
delete[] read_block;
132132
}
133133

134-
void test_spif_unaligned_program()
134+
void test_spif_unaligned_erase()
135135
{
136-
utest_printf("\nTest Unaligned Program Starts..\n");
136+
utest_printf("\nTest Unaligned Erase Starts..\n");
137137

138138
SPIFBlockDevice blockD(MBED_CONF_SPIF_DRIVER_SPI_MOSI, MBED_CONF_SPIF_DRIVER_SPI_MISO, MBED_CONF_SPIF_DRIVER_SPI_CLK,
139139
MBED_CONF_SPIF_DRIVER_SPI_CS);
@@ -153,57 +153,42 @@ void test_spif_unaligned_program()
153153
}
154154
}
155155

156-
bd_size_t block_size = blockD.get_erase_size();
156+
bd_addr_t addr = 0;
157+
bd_size_t sector_erase_size = blockD.get_erase_size(addr);
157158
unsigned addrwidth = ceil(log(float(blockD.size() - 1)) / log(float(16))) + 1;
158159

159-
uint8_t *write_block = new (std::nothrow) uint8_t[block_size];
160-
uint8_t *read_block = new (std::nothrow) uint8_t[block_size];
161-
if (!write_block || !read_block ) {
162-
utest_printf("\n Not enough memory for test");
163-
goto end;
164-
}
165-
166-
{
167-
bd_addr_t block = (rand() * block_size) % blockD.size() + 1;
160+
utest_printf("\ntest %0*llx:%llu...", addrwidth, addr, sector_erase_size);
168161

169-
// Use next random number as temporary seed to keep
170-
// the address progressing in the pseudorandom sequence
171-
unsigned seed = rand();
162+
//unaligned start address
163+
addr += 1;
164+
err = blockD.erase(addr, sector_erase_size - 1);
165+
TEST_ASSERT_EQUAL(SPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
172166

173-
// Fill with random sequence
174-
srand(seed);
175-
for (bd_size_t i_ind = 0; i_ind < block_size; i_ind++) {
176-
write_block[i_ind] = 0xff & rand();
177-
}
167+
err = blockD.erase(addr, sector_erase_size);
168+
TEST_ASSERT_EQUAL(SPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
178169

179-
// Write, sync, and read the block
180-
utest_printf("\ntest %0*llx:%llu...", addrwidth, block, block_size);
170+
err = blockD.erase(addr, 1);
171+
TEST_ASSERT_EQUAL(SPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
181172

182-
err = blockD.erase(block, block_size);
183-
TEST_ASSERT_EQUAL(0, err);
173+
//unaligned end address
174+
addr = 0;
184175

185-
//err = blockD.erase(block+4096, block_size);
186-
//TEST_ASSERT_EQUAL(0, err);
176+
err = blockD.erase(addr, 1);
177+
TEST_ASSERT_EQUAL(SPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
187178

188-
err = blockD.program(write_block, block, block_size);
189-
TEST_ASSERT_EQUAL(0, err);
179+
err = blockD.erase(addr, sector_erase_size + 1);
180+
TEST_ASSERT_EQUAL(SPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
190181

191-
err = blockD.read(read_block, block, block_size);
192-
TEST_ASSERT_EQUAL(0, err);
182+
//erase size exceeds flash device size
183+
err = blockD.erase(addr, blockD.size() + 1);
184+
TEST_ASSERT_EQUAL(SPIF_BD_ERROR_INVALID_ERASE_PARAMS, err);
193185

194-
// Check that the data was unmodified
195-
srand(seed);
196-
for (bd_size_t i_ind = 0; i_ind < block_size; i_ind++) {
197-
//printf("index %d\n", i_ind);
198-
TEST_ASSERT_EQUAL(0xff & rand(), read_block[i_ind]);
199-
}
186+
// Valid erase
187+
err = blockD.erase(addr, sector_erase_size);
188+
TEST_ASSERT_EQUAL(SPIF_BD_ERROR_OK, err);
200189

201-
err = blockD.deinit();
202-
TEST_ASSERT_EQUAL(0, err);
203-
}
204-
end:
205-
delete[] write_block;
206-
delete[] read_block;
190+
err = blockD.deinit();
191+
TEST_ASSERT_EQUAL(0, err);
207192
}
208193

209194
static void test_spif_thread_job(void *vBlockD/*, int thread_num*/)
@@ -282,7 +267,7 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
282267
}
283268

284269
Case cases[] = {
285-
Case("Testing unaligned program blocks", test_spif_unaligned_program),
270+
Case("Testing unaligned erase blocks", test_spif_unaligned_erase),
286271
Case("Testing read write random blocks", test_spif_random_program_read_erase),
287272
Case("Testing Multi Threads Erase Program Read", test_spif_multi_threads)
288273
};

0 commit comments

Comments
 (0)