From 0d04c805acd1e1a404fd17af26c5090bc5d0378d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martijn=20Th=C3=A9?= Date: Fri, 26 Jan 2018 08:26:09 +0100 Subject: [PATCH] Zero out unused bytes in snapshots (#1980) Compiled code blocks are sized in multiples of JMEM_ALIGNMENT, but it's possible that some bytes at the end remain unused and get filled with junk. This causes snapshot output to become nondeterministic. To fix this, zero out the compiled code buffer before using it. JerryScript-DCO-1.0-Signed-off-by: Martijn The martijn.the@intel.com --- jerry-core/parser/js/js-parser.c | 14 ++++++++++++++ tests/unit-core/test-snapshot.c | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 5d31ed847..fcd5908b1 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -1379,6 +1379,9 @@ parser_post_processing (parser_context_t *context_p) /**< context */ size_t offset; size_t length; size_t total_size; +#ifdef JERRY_ENABLE_SNAPSHOT_SAVE + size_t total_size_used; +#endif size_t initializers_length; uint8_t real_offset; uint8_t *byte_code_p; @@ -1610,10 +1613,21 @@ parser_post_processing (parser_context_t *context_p) /**< context */ } total_size += length + context_p->literal_count * sizeof (jmem_cpointer_t); +#ifdef JERRY_ENABLE_SNAPSHOT_SAVE + total_size_used = total_size; +#endif total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT); compiled_code_p = (ecma_compiled_code_t *) parser_malloc (context_p, total_size); +#ifdef JERRY_ENABLE_SNAPSHOT_SAVE + // Avoid getting junk bytes at the end when bytes at the end remain unused: + if (total_size_used < total_size) + { + memset (((uint8_t *) compiled_code_p) + total_size_used, 0, total_size - total_size_used); + } +#endif + #ifdef JMEM_STATS jmem_stats_allocate_byte_code_bytes (total_size); #endif /* JMEM_STATS */ diff --git a/tests/unit-core/test-snapshot.c b/tests/unit-core/test-snapshot.c index 8ed1228d5..228a11873 100644 --- a/tests/unit-core/test-snapshot.c +++ b/tests/unit-core/test-snapshot.c @@ -123,6 +123,26 @@ main (void) global_mode_snapshot_buffer, SNAPSHOT_BUFFER_SIZE); TEST_ASSERT (global_mode_snapshot_size != 0); + + /* Check the snapshot data. Unused bytes should be filled with zeroes */ + const uint8_t expected_data[] = + { + 0x4A, 0x52, 0x52, 0x59, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x28, 0x00, + 0xB7, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x47, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x14, 0x00, 0x73, 0x74, + 0x72, 0x69, 0x6E, 0x67, 0x20, 0x66, 0x72, 0x6F, + 0x6D, 0x20, 0x73, 0x6E, 0x61, 0x70, 0x73, 0x68, + 0x6F, 0x74, 0x00, 0x00, + }; + TEST_ASSERT (sizeof (expected_data) == global_mode_snapshot_size); + TEST_ASSERT (0 == memcmp (expected_data, global_mode_snapshot_buffer, sizeof (expected_data))); + jerry_cleanup (); jerry_init (JERRY_INIT_EMPTY);