Skip to content

Commit 67f3b34

Browse files
author
Seppo Takalo
committed
TDBStore: Must use work buffer with size of programming unit.
In TDBStore::copy_record() we must prepare our content in size of full programming unit. If we don't have big enough buffer we end up writing garbage from our stack. In most cases, this is prevent by usage of output buffer, but when writing the record header, due the padding, we must write one full programming unit.
1 parent ad40b1b commit 67f3b34

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

storage/kvstore/source/TDBStore.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ typedef struct {
7777
uint32_t crc;
7878
} reserved_trailer_t;
7979

80-
static const uint32_t work_buf_size = 64;
8180
static const uint32_t initial_crc = 0xFFFFFFFF;
8281
static const uint32_t initial_max_keys = 16;
8382

@@ -327,7 +326,7 @@ int TDBStore::read_record(uint8_t area, uint32_t offset, char *key,
327326
user_key_ptr[key_size] = '\0';
328327
} else {
329328
dest_buf = _work_buf;
330-
chunk_size = std::min(key_size, work_buf_size);
329+
chunk_size = std::min(key_size, _prog_size);
331330
}
332331
} else {
333332
// This means that we're on the data part
@@ -337,13 +336,13 @@ int TDBStore::read_record(uint8_t area, uint32_t offset, char *key,
337336
// 3. After actual part is finished - read to work buffer
338337
// 4. Copy data flag not set - read to work buffer
339338
if (curr_data_offset < data_offset) {
340-
chunk_size = std::min((size_t)work_buf_size, (size_t)(data_offset - curr_data_offset));
339+
chunk_size = std::min((size_t)_prog_size, (size_t)(data_offset - curr_data_offset));
341340
dest_buf = _work_buf;
342341
} else if (copy_data && (curr_data_offset < data_offset + actual_data_size)) {
343342
chunk_size = actual_data_size;
344343
dest_buf = static_cast<uint8_t *>(data_buf);
345344
} else {
346-
chunk_size = std::min(work_buf_size, total_size);
345+
chunk_size = std::min(_prog_size, total_size);
347346
dest_buf = _work_buf;
348347
}
349348
}
@@ -824,17 +823,19 @@ int TDBStore::copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_o
824823
uint32_t &to_next_offset)
825824
{
826825
int ret;
827-
record_header_t header;
826+
record_header_t *header = (record_header_t *) _work_buf;
828827
uint32_t total_size;
829828
uint16_t chunk_size;
830829

831-
ret = read_area(from_area, from_offset, sizeof(header), &header);
830+
memset(_work_buf, 0, _prog_size);
831+
832+
ret = read_area(from_area, from_offset, sizeof(header), header);
832833
if (ret) {
833834
return ret;
834835
}
835836

836837
total_size = align_up(sizeof(record_header_t), _prog_size) +
837-
align_up(header.key_size + header.data_size, _prog_size);;
838+
align_up(header->key_size + header->data_size, _prog_size);;
838839

839840

840841
if (to_offset + total_size > _size) {
@@ -847,7 +848,7 @@ int TDBStore::copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_o
847848
}
848849

849850
chunk_size = align_up(sizeof(record_header_t), _prog_size);
850-
ret = write_area(1 - from_area, to_offset, chunk_size, &header);
851+
ret = write_area(1 - from_area, to_offset, chunk_size, header);
851852
if (ret) {
852853
return ret;
853854
}
@@ -857,7 +858,7 @@ int TDBStore::copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_o
857858
total_size -= chunk_size;
858859

859860
while (total_size) {
860-
chunk_size = std::min(total_size, work_buf_size);
861+
chunk_size = std::min(total_size, _prog_size);
861862
ret = read_area(from_area, from_offset, chunk_size, _work_buf);
862863
if (ret) {
863864
return ret;
@@ -1041,7 +1042,7 @@ int TDBStore::init()
10411042
}
10421043

10431044
_prog_size = _bd->get_program_size();
1044-
_work_buf = new uint8_t[work_buf_size];
1045+
_work_buf = new uint8_t[_prog_size];
10451046
_key_buf = new char[MAX_KEY_SIZE];
10461047
_inc_set_handle = new inc_set_handle_t;
10471048
memset(_inc_set_handle, 0, sizeof(inc_set_handle_t));

0 commit comments

Comments
 (0)