Skip to content

Commit fef7bd0

Browse files
committed
fuzzer fixes
1 parent b42eac9 commit fef7bd0

7 files changed

Lines changed: 42 additions & 78 deletions

File tree

app/src/borsh.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void print_string(const char *str) {
7373
MEMCPY(print, str, strlen(str));
7474
ZEMU_LOGF(100, "%s\n", print);
7575
#else
76-
printf("%s\n", str);
76+
// printf("%s\n", str);
7777
#endif
7878
}
7979

app/src/borsh.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ extern "C" {
3434
static inline parser_error_t read_u##bits(parser_context_t *ctx, uint##bits##_t *val) { \
3535
CHECK_INPUT(ctx); \
3636
CHECK_INPUT(val); \
37-
*val = *(uint##bits##_t *)(ctx->buffer.ptr + ctx->offset); \
37+
if (ctx->offset > ctx->buffer.len - OFFSET_U##bits) { \
38+
return parser_no_data; \
39+
} \
40+
MEMCPY(val, ctx->buffer.ptr + ctx->offset, sizeof(uint##bits##_t)); \
3841
CTX_CHECK_AND_ADVANCE(ctx, OFFSET_U##bits); \
3942
return parser_ok; \
4043
}

app/src/schema_proof.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ static parser_error_t hash_index_leaf(merkle_leaves_data_t *leaves, uint64_t ind
110110
uint32_t data_length = 0;
111111
CHECK_ERROR(read_u32(&leaves->data, &data_length));
112112

113+
// Bounds check to prevent buffer overflow
114+
if (leaves->data.offset + data_length > leaves->data.buffer.len) {
115+
return parser_unexpected_buffer_end;
116+
}
117+
113118
// Compute hash from entry and store it in proof->hash
114119
crypto_sha256_init();
115120
crypto_sha256_update(&LEAF_PREFIX, 1);

app/src/schema_reader.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,17 @@ parser_error_t read_structured_display_overrides(parser_context_t *ctx, structur
115115
CHECK_INPUT(ctx);
116116

117117
// read has_title_elements
118-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&display->has_title_elements));
118+
uint8_t tmp = 0;
119+
CHECK_ERROR(read_u8(ctx, &tmp));
120+
display->has_title_elements = (tmp != 0);
119121
if (display->has_title_elements) {
120122
// read title_elements
121123
CHECK_ERROR(read_u64(ctx, (uint64_t *)&display->title_elements));
122124
}
123125

124126
// read has_title_lines
125-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&display->has_title_lines));
127+
CHECK_ERROR(read_u8(ctx, &tmp));
128+
display->has_title_lines = (tmp != 0);
126129
if (display->has_title_lines) {
127130
// read title_lines
128131
CHECK_ERROR(read_u64(ctx, (uint64_t *)&display->title_lines));
@@ -155,7 +158,9 @@ parser_error_t read_primitive_byte_array(parser_context_t *ctx, primitive_byte_a
155158
CHECK_ERROR(read_byte_display(ctx, &primitive->display));
156159

157160
// read has_name_registry
158-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&primitive->has_name_registry));
161+
uint8_t tmp = 0;
162+
CHECK_ERROR(read_u8(ctx, &tmp));
163+
primitive->has_name_registry = (tmp != 0);
159164

160165
// read name_registry
161166
if (primitive->has_name_registry) {
@@ -177,7 +182,9 @@ parser_error_t read_primitive_byte_vec(parser_context_t *ctx, primitive_byte_vec
177182
CHECK_ERROR(read_byte_display(ctx, &primitive->display));
178183

179184
// read has_name_registry
180-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&primitive->has_name_registry));
185+
uint8_t tmp = 0;
186+
CHECK_ERROR(read_u8(ctx, &tmp));
187+
primitive->has_name_registry = (tmp != 0);
181188

182189
// read name_registry
183190
if (primitive->has_name_registry) {
@@ -269,7 +276,9 @@ parser_error_t read_enum_variant(parser_context_t *ctx, enum_variant_t *variant)
269276
CHECK_ERROR(read_u8(ctx, (uint8_t *)&variant->hide_tag));
270277

271278
// read has_value
272-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&variant->has_value));
279+
uint8_t tmp = 0;
280+
CHECK_ERROR(read_u8(ctx, &tmp));
281+
variant->has_value = (tmp != 0);
273282
if (variant->has_value) {
274283
// read value
275284
CHECK_ERROR(read_link(ctx, &variant->value));
@@ -374,7 +383,9 @@ parser_error_t read_struct(parser_context_t *ctx, schema_struct_t *schema_struct
374383
}
375384

376385
// read has_show_as
377-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&schema_struct->has_show_as));
386+
uint8_t tmp = 0;
387+
CHECK_ERROR(read_u8(ctx, &tmp));
388+
schema_struct->has_show_as = (tmp != 0);
378389
if (schema_struct->has_show_as) {
379390
CHECK_ERROR(read_u32(ctx, (uint32_t *)&schema_struct->show_as.len));
380391
if (schema_struct->show_as.len == 0) {
@@ -387,7 +398,8 @@ parser_error_t read_struct(parser_context_t *ctx, schema_struct_t *schema_struct
387398
}
388399

389400
// read has_structured_show_as
390-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&schema_struct->has_structured_show_as));
401+
CHECK_ERROR(read_u8(ctx, &tmp));
402+
schema_struct->has_structured_show_as = (tmp != 0);
391403
if (schema_struct->has_structured_show_as) {
392404
CHECK_ERROR(read_u32(ctx, (uint32_t *)&schema_struct->structured_show_as.len));
393405
if (schema_struct->structured_show_as.len == 0) {
@@ -424,7 +436,9 @@ parser_error_t read_tuple(parser_context_t *ctx, schema_tuple_t *schema_tuple) {
424436
CHECK_INPUT(ctx);
425437

426438
// read has_show_as
427-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&schema_tuple->has_show_as));
439+
uint8_t tmp = 0;
440+
CHECK_ERROR(read_u8(ctx, &tmp));
441+
schema_tuple->has_show_as = (tmp != 0);
428442
if (schema_tuple->has_show_as) {
429443
CHECK_ERROR(read_u32(ctx, (uint32_t *)&schema_tuple->show_as.len));
430444
if (schema_tuple->show_as.len == 0) {
@@ -437,7 +451,8 @@ parser_error_t read_tuple(parser_context_t *ctx, schema_tuple_t *schema_tuple) {
437451
}
438452

439453
// read has_structured_show_as
440-
CHECK_ERROR(read_u8(ctx, (uint8_t *)&schema_tuple->has_structured_show_as));
454+
CHECK_ERROR(read_u8(ctx, &tmp));
455+
schema_tuple->has_structured_show_as = (tmp != 0);
441456
if (schema_tuple->has_structured_show_as) {
442457
CHECK_ERROR(read_u32(ctx, (uint32_t *)&schema_tuple->structured_show_as.len));
443458
if (schema_tuple->structured_show_as.len == 0) {
@@ -762,6 +777,10 @@ parser_error_t schema_merkle_proofs_read(parser_context_t *ctx, parser_tx_t *txO
762777
CHECK_INPUT(ctx);
763778
CHECK_INPUT(txObj);
764779

780+
if (ctx->buffer.len < 4) {
781+
return parser_no_data;
782+
}
783+
765784
// read leaf data
766785
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proofs.leaves.entries));
767786
const uint8_t *ptr_mem = ctx->buffer.ptr + ctx->offset;

app/src/ui_item_manager.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,5 @@ parser_error_t push_item(parser_tx_t *txObj, primitive_t *primitive, parser_cont
149149
txObj->ui_items_new.items[txObj->ui_items_new.qty].data_context = *data_context;
150150
txObj->ui_items_new.qty++;
151151

152-
for (uint16_t i = 0; i < txObj->ui_items_new.qty; i++) {
153-
print_string("Push item NEW: ");
154-
print_string(txObj->ui_items_new.items[i].title);
155-
print_buffer(&txObj->ui_items_new.items[i].data_context.buffer, "data context");
156-
}
157-
158152
return parser_ok;
159153
}

fuzz/run-fuzzers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
env['UBSAN_OPTIONS'] = 'halt_on_error=1:print_stacktrace=1'
3131

3232
cmd = [fuzz_path, f'-max_total_time={max_time}',
33-
f'-jobs=2'
33+
f'-jobs=1'
3434
f'-max_len={max_len}',
3535
f'-mutate_depth={MUTATE_DEPTH}',
3636
f'-artifact_prefix={artifact_dir}/',

tests/parser_impl.cpp

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -283,72 +283,15 @@ TEST(SCALE, MultiProofTest) {
283283
EXPECT_EQ(memcmp(tx_obj.schema.chain_hash.ptr, expected_hash, CX_SHA256_SIZE), 0) << "Chain hash mismatch";
284284
}
285285

286-
TEST(SCALE, ReadMultiProofUnsignedTransaction) {
286+
TEST(SCALE, Fuzzer) {
287287
parser_context_t ctx = {0};
288288
parser_tx_t tx_obj = {0};
289289
parser_error_t err;
290290
uint8_t buffer[12000];
291-
auto bufferLen = parseHexString(
292-
buffer, sizeof(buffer),
293-
"1a00000059010000000b00000052756e74696d6543616c6c0c0000000400000042616e6b0000010004000000000000001100000053657175656"
294-
"e63657252656769737472790100010016000000000000000b00000056616c7565536574746572020001001d0000000000000012000000417474"
295-
"6573746572496e63656e74697665730300010025000000000000001000000050726f766572496e63656e7469766573040001002a00000000000"
296-
"000080000004163636f756e7473050001002e000000000000000a000000556e697175656e6573730600010033000000000000000a0000004368"
297-
"61696e53746174650700010035000000000000000b000000426c6f6253746f72616765080001003600000000000000090000005061796d61737"
298-
"465720900010037000000000000000300000045766d0a00010051000000000000000d0000004163636573735061747465726e0b000100540000"
299-
"000000000001000014000000020000000100000001000901000000000000000042000000000c0000004d756c746941646472657373020000000"
300-
"80000005374616e64617264000001000a0000000000000002000000566d010001000c0000000000000001000019000000020000000100000000"
301-
"0b00000000000000000000000000000023000000020000000100000001011c000000000000000303000000736f760000000000000000000a000"
302-
"0000d0009000000000000000a000000030008000000000000000a00000003002100000000000000190000000200000001000000002200000000"
303-
"00000000000000000000000d0000000c02000000000000000100080119000000020000000100000000380000000000000000000000000000007"
304-
"8000000000b00000043616c6c4d657373616765030000001100000052656769737465725061796d617374657200000100390000000000000014"
305-
"0000005365745061796572466f7253657175656e6365720100010046000000000000000c000000557064617465506f6c6963790200010047000"
306-
"000000000000000006700000001300000005f5f536f765669727475616c57616c6c65745f43616c6c4d6573736167655f526567697374657250"
307-
"61796d61737465720000000100000006000000706f6c6963790000003a000000000000000000000001030000000000000001020000000000000"
308-
"0b6000000011a0000005061796d6173746572506f6c696379496e697469616c697a6572000000040000001400000064656661756c745f706179"
309-
"65655f706f6c6963790000003b00000000000000000000000600000070617965657300000041000000000000000000000013000000617574686"
310-
"f72697a65645f75706461746572730000000e000000000000000000000015000000617574686f72697a65645f73657175656e63657273000000"
311-
"430000000000000000000000000037000000000b0000005061796565506f6c6963790200000005000000416c6c6f77000001003c00000000000"
312-
"0000400000044656e79010000000000ac00000001240000005f5f536f765669727475616c57616c6c65745f5061796565506f6c6963795f416c"
313-
"6c6f7700000004000000070000006d61785f6665650000000f0000000000000000000000090000006761735f6c696d697400000020000000000"
314-
"00000000000000d0000006d61785f6761735f70726963650000003d0000000000000000000000110000007472616e73616374696f6e5f6c696d"
315-
"697400000040000000000000000000000000000a00000003003e000000000000002e00000001080000004761735072696365000000010000000"
316-
"500000076616c75650000003f00000000000000000000000000120000000c02000000000000000008000000000000000500000003010008010a"
317-
"0000000d004200000000000000280000000200000002000000000900000000000000000000000000003b0000000000000000000000000000003"
318-
"e0000000014000000417574686f72697a656453657175656e636572730200000003000000416c6c00000004000000536f6d6501000100440000"
319-
"0000000000000000c60000000109000000547844657461696c730001370000007b4d6178205072696f72697479204665657c7d7c7b4d6178204"
320-
"665657c7d7c7b476173204c696d69747c7d7c7b436861696e2049447c7d0004000000150000006d61785f7072696f726974795f6665655f6269"
321-
"70730001006a0000000000000000000000070000006d61785f666565000000080000000000000000000000090000006761735f6c696d6974000"
322-
"10020000000000000000000000008000000636861696e5f69640001010008010000000000001400000002000000010000000100080100000000"
323-
"00000000880000000113000000556e7369676e65645472616e73616374696f6e0001120000007b7d7c7b47656e65726174696f6e7d7c7b7d000"
324-
"30000000c00000072756e74696d655f63616c6c0000000300000000000000000000000a00000067656e65726174696f6e000101000801000000"
325-
"000700000064657461696c7300000069000000000000000000000000001a0000000300000000000000080000000000000009000000000000000"
326-
"a000000000000000b000000000000000e000000000000000f000000000000002000000000000000210000000000000022000000000000003700"
327-
"000000000000380000000000000039000000000000003a000000000000003b000000000000003c000000000000003d000000000000003e00000"
328-
"0000000003f00000000000000400000000000000041000000000000004200000000000000430000000000000069000000000000006a00000000"
329-
"0000006b000000000000001000000077acc7048b564d54cfb2cf87279320144ab1a3fd7d71c84c0912051d08ebf36bdf0ff86a776897f89216f"
330-
"36f60dc259efadc0fe96916b464bb0da54ccefd6c4aaed068171d4b762ffb6832ef09b312fa307c6e63842a3ed345f296fe4fdd6b784221aacf"
331-
"4fa025bc5f03c16582f9e4ab4fc1479ce11af5927610c450f8461c11b720318bc1aeeb37557487d8e3029d63c310b136487d5862e3b7e795313"
332-
"7d9222c1a96629574b47179a89ce11de505fc1f972b986eb3216ecdcbea928260316362f0db9c5a1c9552c49c574fd68ced31216afcf50ee00e"
333-
"4037b14f7b815178825370d5c58a70ac1bac18a37025400bd9a5c1d8d635b9c02fe561324965c9b325cdeccaa748532eb8c46e2031d355ecd8c"
334-
"d8f49b58540130e8c31312935e1a084114fe6c3a9666ee00ee9f54a171cbcaf9c3d8261acf90902c3cde82a5adf692aa4b4add2c0c43f06ca66"
335-
"475693198153cdb81c8e72dc6096eea71699db04d3934a5ce1176c12b475dd37f6520dc546f61a0fb2a68915590abbdedba9eed5c427ae0d792"
336-
"69b40e78557292c4691beb4d0f1186cd7b77423d9d232d88156a860fe6b6158f4d25b73e714c58dd1ce65723c71311c19d637103647d7d2e422"
337-
"8292ffaa801c77d4ab726b3400e77f090dbc1b39ea47027845b39f9e7dd5ad22fc78b5ed27560feb925637a3a176e3c9e1d357504d186d5fe61"
338-
"40abff97bcb464bcca26c00000000000000f55d28d6582a2e492b325f097e1ebcc0a19eca8f506fb5a7c3473067d48f06f80400000000000000"
339-
"000000006b0000000000000003000000000000000b00000000000000e1100000000000000900000054657374436861696e06010000000900000"
340-
"0746f6b656e5f696473010000002000000017171717171717171717171717171717171717171717171717171717171717060900000054657374"
341-
"546f6b656e77f986b27d5c6e676fdb865f44833b5fe97f5cccafaf5b4733c21ba027f8b725");
342-
343-
auto bufferLen_tx = parseHexString(
344-
buffer + bufferLen, sizeof(buffer),
345-
"09000001102700000000000000000000000000000001d0070000000000000000000000000000d00700000000000000000000000000000132000"
346-
"0000000000001000000000b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0101000000000b0b0b0b0b0b0b0b0b0b0b0b0b"
347-
"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b000000000000000000000000000000000000e876481700000000000000000000000100ca9a3b000000000"
348-
"0ca9a3b00000000e110000000000000a43850ba5603f89c05080e14ff868fec09f35fbfaa3c28ad76258fbac95d7432");
291+
auto bufferLen = parseHexString(buffer, sizeof(buffer), "0a");
349292

350293
ctx.buffer.ptr = buffer;
351-
ctx.buffer.len = bufferLen + bufferLen_tx;
294+
ctx.buffer.len = bufferLen;
352295

353296
// err = parser_parse(&ctx, ctx.buffer.ptr, ctx.buffer.len, &tx_obj);
354297
// EXPECT_EQ(err, parser_ok) << parser_getErrorDescription(err);

0 commit comments

Comments
 (0)