From ff4fb1d87a4ede5ee2474d92dd9896ce978fdccb Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Mon, 31 Aug 2020 17:19:42 +0100 Subject: [PATCH 01/16] Add further scales --- umbra/umbra.c | 24 +++++++++++++++++++----- umbra/umbra.h | 6 +++++- umbra/umbra_64.c | 20 +++++++++++++++++--- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/umbra/umbra.c b/umbra/umbra.c index 07602c85b..9f886ab65 100644 --- a/umbra/umbra.c +++ b/umbra/umbra.c @@ -148,10 +148,18 @@ umbra_map_create(umbra_map_t **map_out, umbra_map_options_t *ops, uint idx) return DRMF_ERROR_NOT_IMPLEMENTED; } switch (ops->scale) { + case UMBRA_MAP_SCALE_DOWN_64X: + map->shift = 6; + break; + case UMBRA_MAP_SCALE_DOWN_32X: + map->shift = 5; + break; case UMBRA_MAP_SCALE_DOWN_8X: + case UMBRA_MAP_SCALE_UP_8X: map->shift = 3; break; case UMBRA_MAP_SCALE_DOWN_4X: + case UMBRA_MAP_SCALE_UP_4X: map->shift = 2; break; case UMBRA_MAP_SCALE_DOWN_2X: @@ -769,21 +777,27 @@ umbra_get_granularity(const umbra_map_t *map, OUT int *scale, OUT bool *is_scale *is_scale_down = UMBRA_MAP_SCALE_IS_DOWN(map->options.scale); switch (map->options.scale) { + case UMBRA_MAP_SCALE_DOWN_64X: + *scale = 64; + break; + case UMBRA_MAP_SCALE_DOWN_32X: + *scale = 32; + break; case UMBRA_MAP_SCALE_DOWN_8X: - *scale = 8; - break; + case UMBRA_MAP_SCALE_UP_8X: + *scale = 8; + break; case UMBRA_MAP_SCALE_DOWN_4X: + case UMBRA_MAP_SCALE_UP_4X: *scale = 4; break; case UMBRA_MAP_SCALE_DOWN_2X: + case UMBRA_MAP_SCALE_UP_2X: *scale = 2; break; case UMBRA_MAP_SCALE_SAME_1X: *scale = 1; break; - case UMBRA_MAP_SCALE_UP_2X: - *scale = 2; - break; default: return DRMF_ERROR; } diff --git a/umbra/umbra.h b/umbra/umbra.h index b2329d121..9656ab7f3 100755 --- a/umbra/umbra.h +++ b/umbra/umbra.h @@ -90,11 +90,15 @@ enum { * 8 if using UMBRA_MAP_SCALE_DOWN_8X mapping scheme. */ typedef enum { + UMBRA_MAP_SCALE_DOWN_64X, /** 64 app byte to 1 shadow byte */ + UMBRA_MAP_SCALE_DOWN_32X, /** 32 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_8X, /** 8 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_4X, /** 4 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_2X, /** 2 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_SAME_1X, /** 1 app byte to 1 shadow byte */ - UMBRA_MAP_SCALE_UP_2X, /** 1 app byte to 2 shadow byte */ + UMBRA_MAP_SCALE_UP_2X, /** 1 app byte to 2 shadow byte */ + UMBRA_MAP_SCALE_UP_4X, /** 1 app byte to 4 shadow bytes */ + UMBRA_MAP_SCALE_UP_8X, /** 1 app byte to 8 shadow bytes */ } umbra_map_scale_t; /** Check if a shadow memory mapping scale is scale up or down. */ diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index f3e0ca03a..870fb92b1 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -320,17 +320,23 @@ static ptr_uint_t map_disp[] = { #ifdef WINDOWS # define WIN8_BASE_DISP 0x02000000000 /* These are for up through Win8. */ - (WIN8_BASE_DISP)<<3, /* UMBRA_MAP_SCALE_DOWN_8X */ + (WIN8_BASE_DISP)<<6, /* UMBRA_MAP_SCALE_DOWN_64X */ + (WIN8_BASE_DISP)<<5, /* UMBRA_MAP_SCALE_DOWN_32X */ + (WIN8_BASE_DISP)<<3, /* UMBRA_MAP_SCALE_DOWN_8X */ (WIN8_BASE_DISP)<<2, /* UMBRA_MAP_SCALE_DOWN_4X */ (WIN8_BASE_DISP)<<1, /* UMBRA_MAP_SCALE_DOWN_2X */ (WIN8_BASE_DISP), /* UMBRA_MAP_SCALE_SAME_1X */ (0x03000000000)>>1, /* UMBRA_MAP_SCALE_UP_2X */ + /* FIXME i#2283: Add disps for other scales. */ #else /* UNIX */ - 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_8X */ + 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_64X */ + 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_32X */ + 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_8X */ 0x0000440000000000, /* UMBRA_MAP_SCALE_DOWN_4X */ 0x0000220000000000, /* UMBRA_MAP_SCALE_DOWN_2X */ 0x0000120000000000, /* UMBRA_MAP_SCALE_SAME_1X */ PIE_DEF_SEG_2X_DISP, /* UMBRA_MAP_SCALE_UP_2X */ + /* FIXME i#2283: Add disps for other scales. */ #endif }; @@ -741,6 +747,11 @@ drmf_status_t umbra_map_arch_init(umbra_map_t *map, umbra_map_options_t *ops) { uint i; + if (map->options.scale > UMBRA_MAP_SCALE_UP_2X){ + /* XXX i#2283: Add support for more scaled-up granularities. */ + ASSERT(false, "scale not yet implemented for 64-bit") + return DRMF_ERROR_NOT_IMPLEMENTED; + } if (UMBRA_MAP_SCALE_IS_UP(map->options.scale)) { map->app_block_size = ALLOC_UNIT_SIZE; map->shadow_block_size = @@ -1183,7 +1194,10 @@ umbra_insert_app_to_shadow_arch(void *drcontext, opnd_create_reg(reg_addr), OPND_CREATE_ABSMEM(&map->disp, OPSZ_PTR))); - if (map->options.scale == UMBRA_MAP_SCALE_UP_2X) { + if (map->options.scale >= UMBRA_MAP_SCALE_UP_2X) { + /* XXX i#2283: To assert remove when we support more granularities. */ + ASSERT(map->options.scale == UMBRA_MAP_SCALE_UP_2X, "invalid scale"); + PRE(ilist, where, INSTR_CREATE_shl(drcontext, opnd_create_reg(reg_addr), OPND_CREATE_INT8(map->shift))); From c4eb2d7af6fed97b35ca00732f123783bbcf4b59 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Mon, 31 Aug 2020 17:28:29 +0100 Subject: [PATCH 02/16] Arrange spaces --- umbra/umbra.c | 28 ++++++++++++++-------------- umbra/umbra_64.c | 8 ++++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/umbra/umbra.c b/umbra/umbra.c index 9f886ab65..f27d86091 100644 --- a/umbra/umbra.c +++ b/umbra/umbra.c @@ -148,12 +148,12 @@ umbra_map_create(umbra_map_t **map_out, umbra_map_options_t *ops, uint idx) return DRMF_ERROR_NOT_IMPLEMENTED; } switch (ops->scale) { - case UMBRA_MAP_SCALE_DOWN_64X: - map->shift = 6; - break; - case UMBRA_MAP_SCALE_DOWN_32X: - map->shift = 5; - break; + case UMBRA_MAP_SCALE_DOWN_64X: + map->shift = 6; + break; + case UMBRA_MAP_SCALE_DOWN_32X: + map->shift = 5; + break; case UMBRA_MAP_SCALE_DOWN_8X: case UMBRA_MAP_SCALE_UP_8X: map->shift = 3; @@ -777,16 +777,16 @@ umbra_get_granularity(const umbra_map_t *map, OUT int *scale, OUT bool *is_scale *is_scale_down = UMBRA_MAP_SCALE_IS_DOWN(map->options.scale); switch (map->options.scale) { - case UMBRA_MAP_SCALE_DOWN_64X: - *scale = 64; - break; + case UMBRA_MAP_SCALE_DOWN_64X: + *scale = 64; + break; case UMBRA_MAP_SCALE_DOWN_32X: - *scale = 32; - break; + *scale = 32; + break; case UMBRA_MAP_SCALE_DOWN_8X: - case UMBRA_MAP_SCALE_UP_8X: - *scale = 8; - break; + case UMBRA_MAP_SCALE_UP_8X: + *scale = 8; + break; case UMBRA_MAP_SCALE_DOWN_4X: case UMBRA_MAP_SCALE_UP_4X: *scale = 4; diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index 870fb92b1..93d07ea3c 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -320,9 +320,9 @@ static ptr_uint_t map_disp[] = { #ifdef WINDOWS # define WIN8_BASE_DISP 0x02000000000 /* These are for up through Win8. */ - (WIN8_BASE_DISP)<<6, /* UMBRA_MAP_SCALE_DOWN_64X */ - (WIN8_BASE_DISP)<<5, /* UMBRA_MAP_SCALE_DOWN_32X */ - (WIN8_BASE_DISP)<<3, /* UMBRA_MAP_SCALE_DOWN_8X */ + (WIN8_BASE_DISP)<<6, /* UMBRA_MAP_SCALE_DOWN_64X */ + (WIN8_BASE_DISP)<<5, /* UMBRA_MAP_SCALE_DOWN_32X */ + (WIN8_BASE_DISP)<<3, /* UMBRA_MAP_SCALE_DOWN_8X */ (WIN8_BASE_DISP)<<2, /* UMBRA_MAP_SCALE_DOWN_4X */ (WIN8_BASE_DISP)<<1, /* UMBRA_MAP_SCALE_DOWN_2X */ (WIN8_BASE_DISP), /* UMBRA_MAP_SCALE_SAME_1X */ @@ -331,7 +331,7 @@ static ptr_uint_t map_disp[] = { #else /* UNIX */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_64X */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_32X */ - 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_8X */ + 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_8X */ 0x0000440000000000, /* UMBRA_MAP_SCALE_DOWN_4X */ 0x0000220000000000, /* UMBRA_MAP_SCALE_DOWN_2X */ 0x0000120000000000, /* UMBRA_MAP_SCALE_SAME_1X */ From 0560e217f89578f69065dfcce935965f54ee7ff8 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Mon, 31 Aug 2020 17:52:00 +0100 Subject: [PATCH 03/16] Add missing semi-colon --- umbra/umbra_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index 93d07ea3c..1b32b6231 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -749,7 +749,7 @@ umbra_map_arch_init(umbra_map_t *map, umbra_map_options_t *ops) uint i; if (map->options.scale > UMBRA_MAP_SCALE_UP_2X){ /* XXX i#2283: Add support for more scaled-up granularities. */ - ASSERT(false, "scale not yet implemented for 64-bit") + ASSERT(false, "scale not yet implemented for 64-bit"); return DRMF_ERROR_NOT_IMPLEMENTED; } if (UMBRA_MAP_SCALE_IS_UP(map->options.scale)) { From a7e0ca9f72f31f4d755ec9f1a42968c2049b65de Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Mon, 31 Aug 2020 18:39:24 +0100 Subject: [PATCH 04/16] Add missing scales --- umbra/umbra_64.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index 1b32b6231..797ff8567 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -347,11 +347,14 @@ static ptr_uint_t map_disp[] = { /* 0x700' also does not work for UP_2X. */ # define WIN81_BASE_DISP_UP2 0xb0000000000 static ptr_uint_t map_disp_win81[] = { + (WIN81_BASE_DISP)<<6, /* UMBRA_MAP_SCALE_DOWN_64X */ + (WIN81_BASE_DISP)<<5, /* UMBRA_MAP_SCALE_DOWN_32X */ (WIN81_BASE_DISP)<<3, /* UMBRA_MAP_SCALE_DOWN_8X */ (WIN81_BASE_DISP)<<2, /* UMBRA_MAP_SCALE_DOWN_4X */ (WIN81_BASE_DISP_DOWN2)<<1, /* UMBRA_MAP_SCALE_DOWN_2X */ (WIN81_BASE_DISP), /* UMBRA_MAP_SCALE_SAME_1X */ (WIN81_BASE_DISP_UP2)>>1, /* UMBRA_MAP_SCALE_UP_2X */ + /* FIXME i#2283: Add disps for other scales. */ }; #endif @@ -431,6 +434,12 @@ umbra_xl8_app_to_shadow(const umbra_map_t *map, app_pc pc) if (pc != 0 && addr == map->disp) addr += (map->mask + 1); switch (map->options.scale) { + case UMBRA_MAP_SCALE_DOWN_64X: + addr >>= 6; + break; + case UMBRA_MAP_SCALE_DOWN_32X: + addr >>= 5; + break; case UMBRA_MAP_SCALE_DOWN_8X: addr >>= 3; break; @@ -445,6 +454,12 @@ umbra_xl8_app_to_shadow(const umbra_map_t *map, app_pc pc) case UMBRA_MAP_SCALE_UP_2X: addr <<= 1; break; + case UMBRA_MAP_SCALE_UP_4X: + addr <<= 2; + break; + case UMBRA_MAP_SCALE_UP_8X: + addr <<= 3; + break; default: ASSERT(false, "invalid scale"); } From 0452afb862f8f6a7ba924adfe7860ee6992f0f7e Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Mon, 31 Aug 2020 20:59:04 +0100 Subject: [PATCH 05/16] Add disps --- umbra/umbra_64.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index 797ff8567..c257b25b5 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -327,7 +327,9 @@ static ptr_uint_t map_disp[] = { (WIN8_BASE_DISP)<<1, /* UMBRA_MAP_SCALE_DOWN_2X */ (WIN8_BASE_DISP), /* UMBRA_MAP_SCALE_SAME_1X */ (0x03000000000)>>1, /* UMBRA_MAP_SCALE_UP_2X */ - /* FIXME i#2283: Add disps for other scales. */ + 0x00002E0000000000, /* UMBRA_MAP_SCALE_UP_4X */ + 0x0000004000000000, /* UMBRA_MAP_SCALE_UP_8X */ + /* FIXME i#2283: Add disps for other scales. */ #else /* UNIX */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_64X */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_32X */ @@ -336,7 +338,8 @@ static ptr_uint_t map_disp[] = { 0x0000220000000000, /* UMBRA_MAP_SCALE_DOWN_2X */ 0x0000120000000000, /* UMBRA_MAP_SCALE_SAME_1X */ PIE_DEF_SEG_2X_DISP, /* UMBRA_MAP_SCALE_UP_2X */ - /* FIXME i#2283: Add disps for other scales. */ + 0x000007E000000000, /* UMBRA_MAP_SCALE_UP_4X */ + 0x000008E000000000, /* UMBRA_MAP_SCALE_UP_8X */ #endif }; @@ -354,7 +357,8 @@ static ptr_uint_t map_disp_win81[] = { (WIN81_BASE_DISP_DOWN2)<<1, /* UMBRA_MAP_SCALE_DOWN_2X */ (WIN81_BASE_DISP), /* UMBRA_MAP_SCALE_SAME_1X */ (WIN81_BASE_DISP_UP2)>>1, /* UMBRA_MAP_SCALE_UP_2X */ - /* FIXME i#2283: Add disps for other scales. */ + 0x000001C000000000, /* UMBRA_MAP_SCALE_UP_4X */ + 0x00000C6000000000, /* UMBRA_MAP_SCALE_UP_8X */ }; #endif From 02e237b6e8ac4a200244d15ac5d8fc06ce0bcd6e Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Tue, 1 Sep 2020 00:21:11 +0100 Subject: [PATCH 06/16] Arrange tests --- tests/framework/umbra_client_allscales.c | 4 ++++ umbra/umbra_64.c | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/framework/umbra_client_allscales.c b/tests/framework/umbra_client_allscales.c index 75892ee2d..aaec950a0 100644 --- a/tests/framework/umbra_client_allscales.c +++ b/tests/framework/umbra_client_allscales.c @@ -75,9 +75,13 @@ test_umbra_mapping(client_id_t id, umbra_map_scale_t scale, const char *label, DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { + test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_64X, "down 64x", 63, true); + test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_32X, "down 32x", 32, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_8X, "down 8x", 8, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_4X, "down 4x", 4, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_2X, "down 2x", 2, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_SAME_1X, "one-to-one", 1, false); test_umbra_mapping(id, UMBRA_MAP_SCALE_UP_2X, "up 2x", 2, false); + test_umbra_mapping(id, UMBRA_MAP_SCALE_UP_4X, "up 4x", 4, false); + test_umbra_mapping(id, UMBRA_MAP_SCALE_UP_8X, "up 8x", 8, false); } diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index c257b25b5..6395d32e9 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -329,7 +329,6 @@ static ptr_uint_t map_disp[] = { (0x03000000000)>>1, /* UMBRA_MAP_SCALE_UP_2X */ 0x00002E0000000000, /* UMBRA_MAP_SCALE_UP_4X */ 0x0000004000000000, /* UMBRA_MAP_SCALE_UP_8X */ - /* FIXME i#2283: Add disps for other scales. */ #else /* UNIX */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_64X */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_32X */ @@ -766,11 +765,6 @@ drmf_status_t umbra_map_arch_init(umbra_map_t *map, umbra_map_options_t *ops) { uint i; - if (map->options.scale > UMBRA_MAP_SCALE_UP_2X){ - /* XXX i#2283: Add support for more scaled-up granularities. */ - ASSERT(false, "scale not yet implemented for 64-bit"); - return DRMF_ERROR_NOT_IMPLEMENTED; - } if (UMBRA_MAP_SCALE_IS_UP(map->options.scale)) { map->app_block_size = ALLOC_UNIT_SIZE; map->shadow_block_size = @@ -1214,9 +1208,6 @@ umbra_insert_app_to_shadow_arch(void *drcontext, OPND_CREATE_ABSMEM(&map->disp, OPSZ_PTR))); if (map->options.scale >= UMBRA_MAP_SCALE_UP_2X) { - /* XXX i#2283: To assert remove when we support more granularities. */ - ASSERT(map->options.scale == UMBRA_MAP_SCALE_UP_2X, "invalid scale"); - PRE(ilist, where, INSTR_CREATE_shl(drcontext, opnd_create_reg(reg_addr), OPND_CREATE_INT8(map->shift))); From f77a614e21a4dac89892c4d63d1870b1e300218b Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Tue, 1 Sep 2020 11:04:07 +0100 Subject: [PATCH 07/16] Fix test --- tests/framework/umbra_client_allscales.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/framework/umbra_client_allscales.c b/tests/framework/umbra_client_allscales.c index aaec950a0..33a5d0976 100644 --- a/tests/framework/umbra_client_allscales.c +++ b/tests/framework/umbra_client_allscales.c @@ -75,7 +75,7 @@ test_umbra_mapping(client_id_t id, umbra_map_scale_t scale, const char *label, DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { - test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_64X, "down 64x", 63, true); + test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_64X, "down 64x", 64, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_32X, "down 32x", 32, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_8X, "down 8x", 8, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_4X, "down 4x", 4, true); From 9b0f62edc935ccbc40f289e234f0515c586c92cc Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Tue, 1 Sep 2020 23:54:59 +0100 Subject: [PATCH 08/16] Remove reserve invariant for scaled-up memory. --- umbra/umbra.h | 19 +++++- umbra/umbra_64.c | 151 ++++++++++++++++++++++++++++++----------------- 2 files changed, 114 insertions(+), 56 deletions(-) diff --git a/umbra/umbra.h b/umbra/umbra.h index 9656ab7f3..575619c8a 100755 --- a/umbra/umbra.h +++ b/umbra/umbra.h @@ -88,6 +88,15 @@ enum { * any Umbra routine will be automatically aligned for proper translation. * For example, application memory address \p app_addr will be aligned to * 8 if using UMBRA_MAP_SCALE_DOWN_8X mapping scheme. + * + * \warning For large scaled-ups (i.e., UMBRA_MAP_SCALE_UP_4X and above), + * UMBRA does not reserve regions for shadow's shadow memory. + * Although Umbra does not support the mapping of meta-data to shadow memory, + * such reserve regions make it easy to detect the use of invalid addresses via faults. + * Unfortunately, large scales of shadow memory results in no space for such reserved + * regions. Therefore, when using large scales, it is possible for the tool using UMBRA + * to corrupt the state of app memory or shadow memory if a wild (invalid) app address + * is translated. */ typedef enum { UMBRA_MAP_SCALE_DOWN_64X, /** 64 app byte to 1 shadow byte */ @@ -97,8 +106,14 @@ typedef enum { UMBRA_MAP_SCALE_DOWN_2X, /** 2 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_SAME_1X, /** 1 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_UP_2X, /** 1 app byte to 2 shadow byte */ - UMBRA_MAP_SCALE_UP_4X, /** 1 app byte to 4 shadow bytes */ - UMBRA_MAP_SCALE_UP_8X, /** 1 app byte to 8 shadow bytes */ + UMBRA_MAP_SCALE_UP_4X, /** + * 1 app byte to 4 shadow bytes. + * Reserve regions not supported. + */ + UMBRA_MAP_SCALE_UP_8X, /** + * 1 app byte to 8 shadow bytes. + * Reserve regions not supported. + */ } umbra_map_scale_t; /** Check if a shadow memory mapping scale is scale up or down. */ diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index 6395d32e9..9ec5f6c8e 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -425,6 +425,11 @@ static const app_segment_t app_segments_initial_81[] = { #define MAX_NUM_APP_SEGMENTS sizeof(app_segments_initial)/sizeof(app_segments_initial[0]) static app_segment_t app_segments[MAX_NUM_APP_SEGMENTS]; +/* For large scales, we do not add reserve (shadow of shadow) regions due + * to limited space. + */ +#define SUPPORT_RESERVE_FOR_SCALE(scale) ((scale) <= UMBRA_MAP_SCALE_UP_2X) + /*************************************************************************** * UTILITY ROUTINES */ @@ -497,10 +502,15 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) size = size / map->shadow_block_size / BIT_PER_BYTE; seg->shadow_bitmap[seg_map_idx] = global_alloc(size, HEAPSTAT_SHADOW); memset(seg->shadow_bitmap[seg_map_idx], 0, size); - seg->reserve_base[seg_map_idx] = - umbra_xl8_app_to_shadow(map, seg->shadow_base[seg_map_idx]); - seg->reserve_end[seg_map_idx] = - umbra_xl8_app_to_shadow(map, seg->shadow_end[seg_map_idx]); + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)) { + seg->reserve_base[seg_map_idx] = + umbra_xl8_app_to_shadow(map, seg->shadow_base[seg_map_idx]); + seg->reserve_end[seg_map_idx] = + umbra_xl8_app_to_shadow(map, seg->shadow_end[seg_map_idx]); + }else{ + seg->reserve_base[map->index] = NULL; + seg->reserve_end[map->index] = NULL; + } seg->map[seg_map_idx] = map; /* check conflicts: * we only check conflicts in the same umbra map and assume no conflict @@ -520,18 +530,29 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) if (segment_overlap(base, end, app_segments[i].shadow_base[map_idx], app_segments[i].shadow_end[map_idx]) || - segment_overlap(base, end, - app_segments[i].reserve_base[map_idx], - app_segments[i].reserve_end[map_idx])) { - ELOG(1, "ERROR: new app segment ["PFX", "PFX")" - " conflicts with app seg ["PFX", "PFX") or its " - "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", - seg->app_base, seg->app_end, - app_segments[i].app_base, app_segments[i].app_end, - app_segments[i].shadow_base[map_idx], - app_segments[i].shadow_end[map_idx], - app_segments[i].reserve_base[map_idx], - app_segments[i].reserve_end[map_idx]); + (SUPPORT_RESERVE_FOR_SCALE(map->options.scale) && + segment_overlap(base, end, + app_segments[i].reserve_base[map_idx], + app_segments[i].reserve_end[map_idx]))) { + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " + "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " + "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", + seg->app_base, seg->app_end, base, end, + app_segments[i].app_base, app_segments[i].app_end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx], + app_segments[i].reserve_base[map_idx], + app_segments[i].reserve_end[map_idx]); + }else{ + ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " + "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " + "shadow ["PFX", "PFX")\n", + seg->app_base, seg->app_end, base, end, + app_segments[i].app_base, app_segments[i].app_end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx]); + } return false; } } @@ -548,50 +569,71 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) segment_overlap(base, end, app_segments[i].shadow_base[map_idx], app_segments[i].shadow_end[map_idx])) || - segment_overlap(base, end, + (SUPPORT_RESERVE_FOR_SCALE(map->options.scale) && segment_overlap(base, end, app_segments[i].reserve_base[map_idx], - app_segments[i].reserve_end[map_idx])) { - ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " - "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " - "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", - seg->app_base, seg->app_end, base, end, - app_segments[i].app_base, app_segments[i].app_end, - app_segments[i].shadow_base[map_idx], - app_segments[i].shadow_end[map_idx], - app_segments[i].reserve_base[map_idx], - app_segments[i].reserve_end[map_idx]); + app_segments[i].reserve_end[map_idx]))) { + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " + "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " + "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", + seg->app_base, seg->app_end, base, end, + app_segments[i].app_base, app_segments[i].app_end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx], + app_segments[i].reserve_base[map_idx], + app_segments[i].reserve_end[map_idx]); + }else{ + ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " + "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " + "shadow ["PFX", "PFX")\n", + seg->app_base, seg->app_end, base, end, + app_segments[i].app_base, app_segments[i].app_end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx]); + } + return false; } } - /* new app-seg's reserve vs other app-seg's app and shadow - * it is ok to overlap with other's reserve. - */ - base = seg->reserve_base[seg_map_idx]; - end = seg->reserve_end[seg_map_idx]; - for (map_idx = 0; map_idx < MAX_NUM_MAPS; map_idx++) { - if (app_segments[i].map[map_idx] == NULL) - continue; - if (segment_overlap(base, end, - app_segments[i].app_base, - app_segments[i].app_end) || - segment_overlap(base, end, - app_segments[i].shadow_base[map_idx], - app_segments[i].shadow_end[map_idx])) { - ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s reserve segment " - "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " - "shadow ["PFX", "PFX")\n", - seg->app_base, seg->app_end, base, end, - app_segments[i].app_base, app_segments[i].app_end, - app_segments[i].shadow_base[map_idx], - app_segments[i].shadow_end[map_idx]); - return false; + + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + /* new app-seg's reserve vs other app-seg's app and shadow + * it is ok to overlap with other's reserve. + */ + base = seg->reserve_base[seg_map_idx]; + end = seg->reserve_end[seg_map_idx]; + for (map_idx = 0; map_idx < MAX_NUM_MAPS; map_idx++) { + if (app_segments[i].map[map_idx] == NULL) + continue; + if (segment_overlap(base, end, + app_segments[i].app_base, + app_segments[i].app_end) || + segment_overlap(base, end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx])) { + ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s reserve segment " + "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " + "shadow ["PFX", "PFX")\n", + seg->app_base, seg->app_end, base, end, + app_segments[i].app_base, app_segments[i].app_end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx]); + return false; + } } } } - LOG(1, "new segment: app ["PFX", "PFX"), shadow ["PFX", "PFX"), " - "reserve ["PFX", "PFX")\n", seg->app_base, seg->app_end, - seg->shadow_base[seg_map_idx], seg->shadow_end[seg_map_idx], - seg->reserve_base[seg_map_idx], seg->reserve_end[seg_map_idx]); + + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + LOG(1, "new segment: app ["PFX", "PFX"), shadow ["PFX", "PFX"), " + "reserve ["PFX", "PFX")\n", seg->app_base, seg->app_end, + seg->shadow_base[seg_map_idx], seg->shadow_end[seg_map_idx], + seg->reserve_base[seg_map_idx], seg->reserve_end[seg_map_idx]); + }else{ + LOG(1, "new segment: app ["PFX", "PFX"), shadow ["PFX", "PFX")\n", + seg->app_base, seg->app_end, + seg->shadow_base[seg_map_idx], seg->shadow_end[seg_map_idx]); + } return true; } @@ -1280,7 +1322,8 @@ umbra_get_shadow_memory_type_arch(umbra_map_t *map, for (i = 0; i < MAX_NUM_APP_SEGMENTS; i++) { if ((shadow_addr >= app_segments[i].app_base && shadow_addr < app_segments[i].app_end) || - (shadow_addr >= app_segments[i].reserve_base[map->index] && + (SUPPORT_RESERVE_FOR_SCALE(map->options.scale) && + shadow_addr >= app_segments[i].reserve_base[map->index] && shadow_addr <= app_segments[i].reserve_end[map->index])) { break; } else if (shadow_addr >= app_segments[i].shadow_base[map->index] && From 2c8e074c6ea69c79e810047592c6d962010bc61a Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Tue, 1 Sep 2020 23:59:04 +0100 Subject: [PATCH 09/16] Arrange comments --- umbra/umbra.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/umbra/umbra.h b/umbra/umbra.h index 575619c8a..deeefac44 100755 --- a/umbra/umbra.h +++ b/umbra/umbra.h @@ -92,11 +92,11 @@ enum { * \warning For large scaled-ups (i.e., UMBRA_MAP_SCALE_UP_4X and above), * UMBRA does not reserve regions for shadow's shadow memory. * Although Umbra does not support the mapping of meta-data to shadow memory, - * such reserve regions make it easy to detect the use of invalid addresses via faults. - * Unfortunately, large scales of shadow memory results in no space for such reserved - * regions. Therefore, when using large scales, it is possible for the tool using UMBRA - * to corrupt the state of app memory or shadow memory if a wild (invalid) app address - * is translated. + * such reserve regions are placed nonetheless to detect the use of invalid addresses + * via faults. Unfortunately, large scales of shadow memory results in no space for + * such reserved regions. Therefore, when using large scales, it is possible for the + * tool using UMBRA to corrupt the state of app memory or shadow memory if a wild + * (invalid) app address is translated. Note this only applies for 64-bit Umbra. */ typedef enum { UMBRA_MAP_SCALE_DOWN_64X, /** 64 app byte to 1 shadow byte */ @@ -108,11 +108,11 @@ typedef enum { UMBRA_MAP_SCALE_UP_2X, /** 1 app byte to 2 shadow byte */ UMBRA_MAP_SCALE_UP_4X, /** * 1 app byte to 4 shadow bytes. - * Reserve regions not supported. + * Reserve regions not supported (applies only for 64-bit). */ UMBRA_MAP_SCALE_UP_8X, /** * 1 app byte to 8 shadow bytes. - * Reserve regions not supported. + * Reserve regions not supported (applies only for 64-bit). */ } umbra_map_scale_t; From 994a8049605b31de53f43b9b09a79bef5899b7a3 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Wed, 2 Sep 2020 10:41:47 +0100 Subject: [PATCH 10/16] Arrange bitmap size --- umbra/umbra_64.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index 9ec5f6c8e..1e56d60a2 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -433,6 +433,28 @@ static app_segment_t app_segments[MAX_NUM_APP_SEGMENTS]; /*************************************************************************** * UTILITY ROUTINES */ +static size_t +get_shadow_bitmap_size(umbra_map_t *map, app_segment_t *seg){ + size_t size = 0; + uint seg_map_idx = map->index; + + ASSERT(seg->shadow_end[seg_map_idx] > seg->shadow_base[seg_map_idx], + "wrong shadow segment range"); + size = seg->shadow_end[seg_map_idx] - seg->shadow_base[seg_map_idx]; + size = size / map->shadow_block_size / BIT_PER_BYTE; + + /* Handle the case where we just need one bit (therefore one byte) + * and as a result size is zero. + */ + if (size == 0) + size++; + + ASSERT(size != 0, + "size cannot be zero"); + return size; +} + + static byte * umbra_xl8_app_to_shadow(const umbra_map_t *map, app_pc pc) { @@ -498,8 +520,7 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) umbra_xl8_app_to_shadow(map, seg->app_end); ASSERT(seg->shadow_end[seg_map_idx] > seg->shadow_base[seg_map_idx], "wrong shadow segment range"); - size = seg->shadow_end[seg_map_idx] - seg->shadow_base[seg_map_idx]; - size = size / map->shadow_block_size / BIT_PER_BYTE; + size = get_shadow_bitmap_size(map, seg); seg->shadow_bitmap[seg_map_idx] = global_alloc(size, HEAPSTAT_SHADOW); memset(seg->shadow_bitmap[seg_map_idx], 0, size); if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)) { @@ -868,8 +889,7 @@ umbra_map_arch_exit(umbra_map_t *map) if (app_segments[i].app_used && app_segments[i].map[map->index] == map) { size_t size; app_segment_t *seg = &app_segments[i]; - size = seg->shadow_end[map->index] - seg->shadow_base[map->index]; - size = size / map->shadow_block_size / BIT_PER_BYTE; + size = get_shadow_bitmap_size(map, seg); global_free(seg->shadow_bitmap[map->index], size, HEAPSTAT_SHADOW); seg->shadow_bitmap[map->index] = NULL; seg->shadow_base[map->index] = NULL; From cd3e2ff5ffd2ffabdd7f79e6f65365e6acef9985 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Tue, 8 Sep 2020 15:54:04 +0100 Subject: [PATCH 11/16] Add review fixes --- umbra/umbra.h | 6 +++--- umbra/umbra_64.c | 23 +++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/umbra/umbra.h b/umbra/umbra.h index deeefac44..b684ce00e 100755 --- a/umbra/umbra.h +++ b/umbra/umbra.h @@ -89,11 +89,11 @@ enum { * For example, application memory address \p app_addr will be aligned to * 8 if using UMBRA_MAP_SCALE_DOWN_8X mapping scheme. * - * \warning For large scaled-ups (i.e., UMBRA_MAP_SCALE_UP_4X and above), - * UMBRA does not reserve regions for shadow's shadow memory. + * \warning For large scale-ups (i.e., UMBRA_MAP_SCALE_UP_4X and above), + * Umbra does not reserve regions for shadow's shadow memory. * Although Umbra does not support the mapping of meta-data to shadow memory, * such reserve regions are placed nonetheless to detect the use of invalid addresses - * via faults. Unfortunately, large scales of shadow memory results in no space for + * via faults. Unfortunately, large scales of shadow memory result in no space for * such reserved regions. Therefore, when using large scales, it is possible for the * tool using UMBRA to corrupt the state of app memory or shadow memory if a wild * (invalid) app address is translated. Note this only applies for 64-bit Umbra. diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index 1e56d60a2..eff8416c0 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -434,12 +434,12 @@ static app_segment_t app_segments[MAX_NUM_APP_SEGMENTS]; * UTILITY ROUTINES */ static size_t -get_shadow_bitmap_size(umbra_map_t *map, app_segment_t *seg){ +get_shadow_bitmap_size(umbra_map_t *map, app_segment_t *seg) { size_t size = 0; uint seg_map_idx = map->index; ASSERT(seg->shadow_end[seg_map_idx] > seg->shadow_base[seg_map_idx], - "wrong shadow segment range"); + "wrong shadow segment range"); size = seg->shadow_end[seg_map_idx] - seg->shadow_base[seg_map_idx]; size = size / map->shadow_block_size / BIT_PER_BYTE; @@ -449,8 +449,7 @@ get_shadow_bitmap_size(umbra_map_t *map, app_segment_t *seg){ if (size == 0) size++; - ASSERT(size != 0, - "size cannot be zero"); + ASSERT(size != 0, "size cannot be zero"); return size; } @@ -528,7 +527,7 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) umbra_xl8_app_to_shadow(map, seg->shadow_base[seg_map_idx]); seg->reserve_end[seg_map_idx] = umbra_xl8_app_to_shadow(map, seg->shadow_end[seg_map_idx]); - }else{ + } else { seg->reserve_base[map->index] = NULL; seg->reserve_end[map->index] = NULL; } @@ -555,7 +554,7 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) segment_overlap(base, end, app_segments[i].reserve_base[map_idx], app_segments[i].reserve_end[map_idx]))) { - if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)) { ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", @@ -565,7 +564,7 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) app_segments[i].shadow_end[map_idx], app_segments[i].reserve_base[map_idx], app_segments[i].reserve_end[map_idx]); - }else{ + } else { ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " "shadow ["PFX", "PFX")\n", @@ -593,7 +592,7 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) (SUPPORT_RESERVE_FOR_SCALE(map->options.scale) && segment_overlap(base, end, app_segments[i].reserve_base[map_idx], app_segments[i].reserve_end[map_idx]))) { - if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)) { ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", @@ -603,7 +602,7 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) app_segments[i].shadow_end[map_idx], app_segments[i].reserve_base[map_idx], app_segments[i].reserve_end[map_idx]); - }else{ + } else { ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " "shadow ["PFX", "PFX")\n", @@ -617,7 +616,7 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) } } - if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)) { /* new app-seg's reserve vs other app-seg's app and shadow * it is ok to overlap with other's reserve. */ @@ -645,12 +644,12 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) } } - if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)){ + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)) { LOG(1, "new segment: app ["PFX", "PFX"), shadow ["PFX", "PFX"), " "reserve ["PFX", "PFX")\n", seg->app_base, seg->app_end, seg->shadow_base[seg_map_idx], seg->shadow_end[seg_map_idx], seg->reserve_base[seg_map_idx], seg->reserve_end[seg_map_idx]); - }else{ + } else { LOG(1, "new segment: app ["PFX", "PFX"), shadow ["PFX", "PFX")\n", seg->app_base, seg->app_end, seg->shadow_base[seg_map_idx], seg->shadow_end[seg_map_idx]); From 0e7da62b6543b3c03cb3783e0a2726b46df3c851 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Sat, 30 Jan 2021 00:22:26 +0000 Subject: [PATCH 12/16] Arrange tab --- umbra/umbra.c | 6 ++++++ umbra/umbra.h | 1 + umbra/umbra_64.c | 35 +++++++++++++++++++++++------------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/umbra/umbra.c b/umbra/umbra.c index f27d86091..ac45e0600 100644 --- a/umbra/umbra.c +++ b/umbra/umbra.c @@ -154,6 +154,9 @@ umbra_map_create(umbra_map_t **map_out, umbra_map_options_t *ops, uint idx) case UMBRA_MAP_SCALE_DOWN_32X: map->shift = 5; break; + case UMBRA_MAP_SCALE_DOWN_16X: + map->shift = 4; + break; case UMBRA_MAP_SCALE_DOWN_8X: case UMBRA_MAP_SCALE_UP_8X: map->shift = 3; @@ -783,6 +786,9 @@ umbra_get_granularity(const umbra_map_t *map, OUT int *scale, OUT bool *is_scale case UMBRA_MAP_SCALE_DOWN_32X: *scale = 32; break; + case UMBRA_MAP_SCALE_DOWN_16X: + *scale = 16; + break; case UMBRA_MAP_SCALE_DOWN_8X: case UMBRA_MAP_SCALE_UP_8X: *scale = 8; diff --git a/umbra/umbra.h b/umbra/umbra.h index b684ce00e..fbd79557e 100755 --- a/umbra/umbra.h +++ b/umbra/umbra.h @@ -101,6 +101,7 @@ enum { typedef enum { UMBRA_MAP_SCALE_DOWN_64X, /** 64 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_32X, /** 32 app byte to 1 shadow byte */ + UMBRA_MAP_SCALE_DOWN_16X, /** 8 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_8X, /** 8 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_4X, /** 4 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_2X, /** 2 app byte to 1 shadow byte */ diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index b77e4255f..c2a43f79b 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -576,18 +576,29 @@ umbra_add_shadow_segment(umbra_map_t *map, app_segment_t *seg) if (segment_overlap(base, end, app_segments[i].shadow_base[map_idx], app_segments[i].shadow_end[map_idx]) || - segment_overlap(base, end, - app_segments[i].reserve_base[map_idx], - app_segments[i].reserve_end[map_idx])) { - ELOG(1, "ERROR: new app segment ["PFX", "PFX")" - " conflicts with app seg ["PFX", "PFX")'s " - "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", - seg->app_base, seg->app_end, - app_segments[i].app_base, app_segments[i].app_end, - app_segments[i].shadow_base[map_idx], - app_segments[i].shadow_end[map_idx], - app_segments[i].reserve_base[map_idx], - app_segments[i].reserve_end[map_idx]); + (SUPPORT_RESERVE_FOR_SCALE(map->options.scale) && + segment_overlap(base, end, + app_segments[i].reserve_base[map_idx], + app_segments[i].reserve_end[map_idx]))) { + if (SUPPORT_RESERVE_FOR_SCALE(map->options.scale)) { + ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " + "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " + "shadow ["PFX", "PFX") or reserve ["PFX", "PFX")\n", + seg->app_base, seg->app_end, base, end, + app_segments[i].app_base, app_segments[i].app_end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx], + app_segments[i].reserve_base[map_idx], + app_segments[i].reserve_end[map_idx]); + } else { + ELOG(1, "ERROR: new app segment ["PFX", "PFX")'s shadow segment " + "["PFX", "PFX") conflicts with app seg ["PFX", "PFX") or its " + "shadow ["PFX", "PFX")\n", + seg->app_base, seg->app_end, base, end, + app_segments[i].app_base, app_segments[i].app_end, + app_segments[i].shadow_base[map_idx], + app_segments[i].shadow_end[map_idx]); + } return false; } } From 25801a751c4da828efa2d0f78b4c0ca7d0875262 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Sun, 31 Jan 2021 02:24:02 +0000 Subject: [PATCH 13/16] Removet abs --- tests/framework/CMakeLists.txt | 9 +- ..._allscales.c => umbra_client_all_scales.c} | 49 +++ .../umbra_client_scale_up_four_inline.c | 283 ++++++++++++++++++ umbra/umbra.h | 2 +- 4 files changed, 341 insertions(+), 2 deletions(-) rename tests/framework/{umbra_client_allscales.c => umbra_client_all_scales.c} (69%) create mode 100644 tests/framework/umbra_client_scale_up_four_inline.c diff --git a/tests/framework/CMakeLists.txt b/tests/framework/CMakeLists.txt index 847290105..656631fd2 100644 --- a/tests/framework/CMakeLists.txt +++ b/tests/framework/CMakeLists.txt @@ -187,6 +187,13 @@ use_DynamoRIO_extension(umbra_test_insert_app_to_shadow.client drutil) target_include_directories(umbra_test_insert_app_to_shadow.client PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +add_drmf_test(umbra_client_scale_up_four_inline umbra_app + umbra_client_scale_up_four_inline.c umbra "" "" ".*TEST PASSED") + use_DynamoRIO_extension(umbra_client_scale_up_four_inline.client drreg) + use_DynamoRIO_extension(umbra_client_scale_up_four_inline.client drutil) + target_include_directories(umbra_client_scale_up_four_inline.client PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}) + # Faulty redzones are only available on 32-bit. if (NOT X64) add_drmf_test(umbra_client_faulty_redzone umbra_app @@ -209,5 +216,5 @@ use_DynamoRIO_extension(umbra_test_consistency.client drutil) target_include_directories(umbra_test_consistency.client PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_drmf_test(umbra_test_allscales umbra_app umbra_client_allscales.c +add_drmf_test(umbra_test_all_scales umbra_app umbra_client_all_scales.c umbra "" "" ".*TEST PASSED") diff --git a/tests/framework/umbra_client_allscales.c b/tests/framework/umbra_client_all_scales.c similarity index 69% rename from tests/framework/umbra_client_allscales.c rename to tests/framework/umbra_client_all_scales.c index 33a5d0976..b3f01e079 100644 --- a/tests/framework/umbra_client_allscales.c +++ b/tests/framework/umbra_client_all_scales.c @@ -44,6 +44,50 @@ (dr_fprintf(STDERR, "ASSERT FAILURE: %s:%d: %s (%s)\n", \ __FILE__, __LINE__, #cond, msg), dr_abort(), 0))) +#define APP_ADDR (app_pc) 0X11111111 +#define NEXT_APP_ADDR APP_ADDR + 1 +#define SHDW_VAL 1 + +static void +test_shadow_scale(umbra_map_t *umbra_map, int scale_val, bool is_scale_down) +{ + drmf_status_t status; + + const size_t shdw_size = scale_val; + size_t shdw_size_test = shdw_size; + byte buf[shdw_size]; + + // Write shadow value. + for (size_t i = 0; i < shdw_size; i++) + buf[i] = SHDW_VAL; + status = umbra_write_shadow_memory(umbra_map, APP_ADDR, 1, &shdw_size_test, buf); + CHECK(status == DRMF_SUCCESS, "Failed to write"); + CHECK(shdw_size_test == shdw_size, "write shadow size should be correct"); + + // Read shadow value. + status = umbra_read_shadow_memory(umbra_map, APP_ADDR, 1, &shdw_size_test, buf); + CHECK(status == DRMF_SUCCESS, "Failed to read"); + CHECK(shdw_size_test == shdw_size, "read shadow size should be correct"); + + for (size_t i = 0; i < shdw_size; i++) + CHECK(buf[i] == SHDW_VAL, "read shadow data should match"); + + // Read shadow value of next app addr. + status = umbra_read_shadow_memory(umbra_map, NEXT_APP_ADDR, 1, &shdw_size_test, buf); + CHECK(status == DRMF_SUCCESS, "Failed to read"); + CHECK(shdw_size_test == shdw_size, "read shadow size should be correct"); + + for (size_t i = 0; i < shdw_size; i++) + CHECK(buf[i] == 0x0, "shadow values of next app addr should be zero"); + + // Write 0. + for (size_t i = 0; i < shdw_size; i++) + buf[i] = SHDW_VAL; + status = umbra_write_shadow_memory(umbra_map, APP_ADDR, 1, &shdw_size_test, buf); + CHECK(status == DRMF_SUCCESS, "Failed to write"); + CHECK(shdw_size_test == shdw_size, "write shadow size should be correct"); +} + static void test_umbra_mapping(client_id_t id, umbra_map_scale_t scale, const char *label, int scale_val, bool is_scale_down) @@ -67,6 +111,10 @@ test_umbra_mapping(client_id_t id, umbra_map_scale_t scale, const char *label, CHECK(false, "failed to get granularity info umbra"); CHECK(scale_val == scale_val_out, "incorrect scale"); CHECK(is_scale_down == is_scale_down_out, "incorrect scale granularity"); + + if (!is_scale_down) + test_shadow_scale(umbra_map, scale_val, is_scale_down); + if (umbra_destroy_mapping(umbra_map) != DRMF_SUCCESS) CHECK(false, "failed to destroy shadow memory mapping"); umbra_exit(); @@ -77,6 +125,7 @@ dr_client_main(client_id_t id, int argc, const char *argv[]) { test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_64X, "down 64x", 64, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_32X, "down 32x", 32, true); + test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_16X, "down 16x", 16, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_8X, "down 8x", 8, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_4X, "down 4x", 4, true); test_umbra_mapping(id, UMBRA_MAP_SCALE_DOWN_2X, "down 2x", 2, true); diff --git a/tests/framework/umbra_client_scale_up_four_inline.c b/tests/framework/umbra_client_scale_up_four_inline.c new file mode 100644 index 000000000..3205335c5 --- /dev/null +++ b/tests/framework/umbra_client_scale_up_four_inline.c @@ -0,0 +1,283 @@ +/* ************************************************************** + * Copyright (c) 2017-2019 Google, Inc. All rights reserved. + * **************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Google, Inc. nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* Tests that there are no conflicts in any scale factor with the target + * application. + */ +#include +#include +#include // for intptr_t + +#include "dr_api.h" +#include "drmgr.h" +#include "drreg.h" +#include "drutil.h" +#include "umbra.h" + +static void +exit_event(void); +static dr_emit_flags_t +event_app_instruction(void *drcontext, void *tag, instrlist_t *ilist, instr_t *where, + bool for_trace, bool translating, void *user_data); +#ifdef WINDOWS +static bool +event_exception_instrumentation(void *drcontext, dr_exception_t *excpt); +#else +static dr_signal_action_t +event_signal_instrumentation(void *drcontext, dr_siginfo_t *info); +#endif + +static umbra_map_t *umbra_map; +// Flag denoting whether check done via clean call is done. +static bool check_called = false; + +/* We don't want a popup so we don't use DR_ASSERT_MSG. */ +#define CHECK(cond, msg) ((void)((cond) ? 0 : \ + (dr_fprintf(STDERR, "ASSERT FAILURE: %s:%d: %s (%s)\n", \ + __FILE__, __LINE__, #cond, msg), dr_abort(), 0))) + +#define TEST(mask, var) (((mask) & (var)) != 0) +#define SHDW_VAL (void *) 0x11111111 + +DR_EXPORT void +dr_client_main(client_id_t id, int argc, const char *argv[]) +{ + drreg_options_t ops = { sizeof(ops), 4, true }; + umbra_map_options_t umbra_map_ops; + + drmgr_init(); + drreg_init(&ops); + + memset(&umbra_map_ops, 0, sizeof(umbra_map_ops)); + umbra_map_ops.scale = IF_X64_ELSE(UMBRA_MAP_SCALE_UP_8X, UMBRA_MAP_SCALE_UP_4X); + umbra_map_ops.flags = + UMBRA_MAP_CREATE_SHADOW_ON_TOUCH | UMBRA_MAP_SHADOW_SHARED_READONLY; + umbra_map_ops.default_value = 0; + umbra_map_ops.default_value_size = 1; + umbra_map_ops.make_redzone_faulty = false; + if (umbra_init(id) != DRMF_SUCCESS) + DR_ASSERT_MSG(false, "fail to init umbra"); + if (umbra_create_mapping(&umbra_map_ops, &umbra_map) != DRMF_SUCCESS) + DR_ASSERT_MSG(false, "fail to create shadow memory mapping"); + drmgr_register_bb_instrumentation_event(NULL, event_app_instruction, NULL); +#ifdef WINDOWS + drmgr_register_exception_event(event_exception_instrumentation); +#else + drmgr_register_signal_event(event_signal_instrumentation); +#endif + dr_register_exit_event(exit_event); +} + + +static void check() +{ + void *drcontext = dr_get_current_drcontext(); + app_pc app_target = (app_pc)dr_read_saved_reg(drcontext, SPILL_SLOT_2); + + drmf_status_t status; + + // Read shadow value. + void *data = NULL; + size_t shdw_size = sizeof(void *); + status = umbra_read_shadow_memory(umbra_map, app_target, 1, &shdw_size, (void *) &data); + CHECK(status == DRMF_SUCCESS, "Failed to read"); + dr_fprintf(STDERR, "SIZES: %p %u %u\n", app_target, shdw_size, sizeof(void *)); + CHECK(shdw_size == sizeof(void *), "read shadow size should be pointer-sized"); + CHECK(data == SHDW_VAL, "read shadow size should be pointer-sized"); + + // Write NULL. + data = NULL; + status = umbra_write_shadow_memory(umbra_map, app_target, 1, &shdw_size, (void *) &data); + CHECK(status == DRMF_SUCCESS, "Failed to write"); + CHECK(shdw_size == sizeof(void *), "write shadow size should be pointer-sized"); + + // Set flag. + check_called = true; +} + +static bool get_mem_src_opnd(instr_t * instr, opnd_t *src_mem_opnd) +{ + DR_ASSERT(src_mem_opnd != NULL); + int src_num = instr_num_srcs(instr); + + for (int i = 0; i < src_num; i++) { + opnd_t src_opnd = instr_get_src(instr, i); + if (opnd_is_memory_reference(src_opnd)) { + *src_mem_opnd = src_opnd; + return true; + } + } + + return false; +} + +static dr_emit_flags_t +event_app_instruction(void *drcontext, void *tag, instrlist_t *ilist, instr_t *where, + bool for_trace, bool translating, void *user_data) +{ + if (instr_reads_memory(where)) { + // Get src mem operand. + opnd_t src_mem_opnd; + bool succ = get_mem_src_opnd(where, &src_mem_opnd); + if (!succ) + return DR_EMIT_DEFAULT; + + // Spill scratch registers. + reg_id_t scratch_reg = DR_REG_NULL; + reg_id_t scratch_reg2 = DR_REG_NULL; + +# ifdef X86 + drvector_t allowed; + drreg_init_and_fill_vector(&allowed, false); + drreg_set_vector_entry(&allowed, DR_REG_XCX, true); +# endif + + if (drreg_reserve_aflags(drcontext, ilist, where) != DRREG_SUCCESS || + drreg_reserve_register(drcontext, ilist, where, IF_X86_ELSE(&allowed, NULL), + &scratch_reg2) != DRREG_SUCCESS || + drreg_reserve_register(drcontext, ilist, where, NULL, &scratch_reg) != + DRREG_SUCCESS) { + DR_ASSERT(false); /* Can't recover. */ + } +# ifdef X86 + drvector_delete(&allowed); +# endif + + succ = drutil_insert_get_mem_addr(drcontext, ilist, where, src_mem_opnd, scratch_reg, scratch_reg2); + DR_ASSERT(succ); + + /* Save the app address to a well-known spill slot, so that the fault handler + * can recover if no shadow memory was installed yet. + */ + dr_save_reg(drcontext, ilist, where, scratch_reg, SPILL_SLOT_2); + + drmf_status_t status = umbra_insert_app_to_shadow(drcontext, umbra_map, ilist, where, scratch_reg, &scratch_reg2, 1); + DR_ASSERT_MSG(status == DRMF_SUCCESS, "fail to insert translation"); + + instr_t *instr; + + // Load shadow value to reg. + opnd_t reg_opnd = opnd_create_reg(scratch_reg2); + opnd_t immed_opnd = opnd_create_immed_int((intptr_t) SHDW_VAL, OPSZ_PTR); + instr = XINST_CREATE_load_int(drcontext, reg_opnd, immed_opnd); + instrlist_meta_preinsert(ilist, where, instr); + + opnd_t shadow_opnd = opnd_create_base_disp(scratch_reg, DR_REG_NULL, 0, 0, OPSZ_PTR); + opnd_t src_opnd = opnd_create_reg(scratch_reg2); + instr = XINST_CREATE_store(drcontext, shadow_opnd, src_opnd); + instr_set_translation(instr, instr_get_app_pc(where)); + instrlist_meta_preinsert(ilist, where, instr); + + // Use a clean call to check write and refresh shadow value. + dr_insert_clean_call(drcontext, ilist, where, check, false, 0); + + if (drreg_unreserve_register(drcontext, ilist, where, scratch_reg) != DRREG_SUCCESS || + drreg_unreserve_register(drcontext, ilist, where, scratch_reg2) != DRREG_SUCCESS || + drreg_unreserve_aflags(drcontext, ilist, where) != DRREG_SUCCESS) + DR_ASSERT(false); + } + + return DR_EMIT_DEFAULT; +} + +static bool +handle_special_shadow_fault(void *drcontext, dr_mcontext_t *raw_mc, app_pc app_shadow) +{ + umbra_shadow_memory_type_t shadow_type; + app_pc app_target; + instr_t inst; + reg_id_t reg; + opnd_t opnd; + + instr_init(drcontext, &inst); + decode(drcontext, raw_mc->pc, &inst); + opnd = instr_get_dst(&inst, 0); + DR_ASSERT_MSG(opnd_is_base_disp(opnd), + "faulty instr should have a mem operand as a destination."); + reg = opnd_get_base(opnd); + instr_free(drcontext, &inst); + + if (umbra_get_shadow_memory_type(umbra_map, app_shadow, &shadow_type) != + DRMF_SUCCESS) { + DR_ASSERT(false); + return true; + } + + if (TEST(UMBRA_SHADOW_MEMORY_TYPE_SHARED, shadow_type)) { + app_target = (app_pc)dr_read_saved_reg(drcontext, SPILL_SLOT_2); + if (umbra_replace_shared_shadow_memory(umbra_map, app_target, &app_shadow) != + DRMF_SUCCESS) { + DR_ASSERT(false); + return true; + } + } + + reg_set_value(reg, raw_mc, (reg_t)app_shadow); + + return false; +} + +#ifdef WINDOWS +bool +event_exception_instrumentation(void *drcontext, dr_exception_t *excpt) +{ + if (excpt->record->ExceptionCode != STATUS_ACCESS_VIOLATION) + return true; + return handle_special_shadow_fault(drcontext, excpt->raw_mcontext, + (byte *)excpt->record->ExceptionInformation[1]); +} +#else +static dr_signal_action_t +event_signal_instrumentation(void *drcontext, dr_siginfo_t *info) +{ + if (info->sig != SIGSEGV && info->sig != SIGBUS) + return DR_SIGNAL_DELIVER; + DR_ASSERT(info->raw_mcontext_valid); + return handle_special_shadow_fault(drcontext, info->raw_mcontext, + info->access_address) + ? DR_SIGNAL_DELIVER + : DR_SIGNAL_SUPPRESS; +} +#endif + +static void +exit_event(void) +{ + DR_ASSERT_MSG(check_called, "check was never performed"); + + if (umbra_destroy_mapping(umbra_map) != DRMF_SUCCESS) + DR_ASSERT(false); + + umbra_exit(); + drreg_exit(); + drmgr_exit(); +} diff --git a/umbra/umbra.h b/umbra/umbra.h index fbd79557e..7658c2813 100755 --- a/umbra/umbra.h +++ b/umbra/umbra.h @@ -101,7 +101,7 @@ enum { typedef enum { UMBRA_MAP_SCALE_DOWN_64X, /** 64 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_32X, /** 32 app byte to 1 shadow byte */ - UMBRA_MAP_SCALE_DOWN_16X, /** 8 app byte to 1 shadow byte */ + UMBRA_MAP_SCALE_DOWN_16X, /** 16 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_8X, /** 8 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_4X, /** 4 app byte to 1 shadow byte */ UMBRA_MAP_SCALE_DOWN_2X, /** 2 app byte to 1 shadow byte */ From 4127cb0ccb9d31b8b505f38775463e4334cd3399 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Sun, 31 Jan 2021 12:39:00 +0000 Subject: [PATCH 14/16] Fix more CI errors --- tests/framework/CMakeLists.txt | 10 +++++----- tests/framework/umbra_client_all_scales.c | 9 ++++----- ...our_inline.c => umbra_client_scale_up_ptr_inline.c} | 1 - 3 files changed, 9 insertions(+), 11 deletions(-) rename tests/framework/{umbra_client_scale_up_four_inline.c => umbra_client_scale_up_ptr_inline.c} (99%) diff --git a/tests/framework/CMakeLists.txt b/tests/framework/CMakeLists.txt index 656631fd2..4ec9d096c 100644 --- a/tests/framework/CMakeLists.txt +++ b/tests/framework/CMakeLists.txt @@ -187,11 +187,11 @@ use_DynamoRIO_extension(umbra_test_insert_app_to_shadow.client drutil) target_include_directories(umbra_test_insert_app_to_shadow.client PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_drmf_test(umbra_client_scale_up_four_inline umbra_app - umbra_client_scale_up_four_inline.c umbra "" "" ".*TEST PASSED") - use_DynamoRIO_extension(umbra_client_scale_up_four_inline.client drreg) - use_DynamoRIO_extension(umbra_client_scale_up_four_inline.client drutil) - target_include_directories(umbra_client_scale_up_four_inline.client PRIVATE +add_drmf_test(umbra_client_scale_up_ptr_inline umbra_app + umbra_client_scale_up_ptr_inline.c umbra "" "" ".*TEST PASSED") + use_DynamoRIO_extension(umbra_client_scale_up_ptr_inline.client drreg) + use_DynamoRIO_extension(umbra_client_scale_up_ptr_inline.client drutil) + target_include_directories(umbra_client_scale_up_ptr_inline.client PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) # Faulty redzones are only available on 32-bit. diff --git a/tests/framework/umbra_client_all_scales.c b/tests/framework/umbra_client_all_scales.c index b3f01e079..52bc39178 100644 --- a/tests/framework/umbra_client_all_scales.c +++ b/tests/framework/umbra_client_all_scales.c @@ -55,9 +55,9 @@ test_shadow_scale(umbra_map_t *umbra_map, int scale_val, bool is_scale_down) const size_t shdw_size = scale_val; size_t shdw_size_test = shdw_size; - byte buf[shdw_size]; + byte buf[50]; // buf size should be big enough - // Write shadow value. + // Write shadow values. for (size_t i = 0; i < shdw_size; i++) buf[i] = SHDW_VAL; status = umbra_write_shadow_memory(umbra_map, APP_ADDR, 1, &shdw_size_test, buf); @@ -72,15 +72,14 @@ test_shadow_scale(umbra_map_t *umbra_map, int scale_val, bool is_scale_down) for (size_t i = 0; i < shdw_size; i++) CHECK(buf[i] == SHDW_VAL, "read shadow data should match"); - // Read shadow value of next app addr. + // Read and check shadow value of next app addr. status = umbra_read_shadow_memory(umbra_map, NEXT_APP_ADDR, 1, &shdw_size_test, buf); CHECK(status == DRMF_SUCCESS, "Failed to read"); CHECK(shdw_size_test == shdw_size, "read shadow size should be correct"); - for (size_t i = 0; i < shdw_size; i++) CHECK(buf[i] == 0x0, "shadow values of next app addr should be zero"); - // Write 0. + // Clear shadow values. for (size_t i = 0; i < shdw_size; i++) buf[i] = SHDW_VAL; status = umbra_write_shadow_memory(umbra_map, APP_ADDR, 1, &shdw_size_test, buf); diff --git a/tests/framework/umbra_client_scale_up_four_inline.c b/tests/framework/umbra_client_scale_up_ptr_inline.c similarity index 99% rename from tests/framework/umbra_client_scale_up_four_inline.c rename to tests/framework/umbra_client_scale_up_ptr_inline.c index 3205335c5..eb6ac2cb8 100644 --- a/tests/framework/umbra_client_scale_up_four_inline.c +++ b/tests/framework/umbra_client_scale_up_ptr_inline.c @@ -83,7 +83,6 @@ dr_client_main(client_id_t id, int argc, const char *argv[]) UMBRA_MAP_CREATE_SHADOW_ON_TOUCH | UMBRA_MAP_SHADOW_SHARED_READONLY; umbra_map_ops.default_value = 0; umbra_map_ops.default_value_size = 1; - umbra_map_ops.make_redzone_faulty = false; if (umbra_init(id) != DRMF_SUCCESS) DR_ASSERT_MSG(false, "fail to init umbra"); if (umbra_create_mapping(&umbra_map_ops, &umbra_map) != DRMF_SUCCESS) From a7683e7f47fdd0227a5d984eca58760750d74e39 Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Sun, 31 Jan 2021 13:22:24 +0000 Subject: [PATCH 15/16] Fix Windows CI error --- tests/framework/CMakeLists.txt | 8 ++--- .../umbra_client_scale_up_ptr_inline.c | 36 +++++++++++++------ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/tests/framework/CMakeLists.txt b/tests/framework/CMakeLists.txt index 4ec9d096c..4c969bb4d 100644 --- a/tests/framework/CMakeLists.txt +++ b/tests/framework/CMakeLists.txt @@ -189,10 +189,10 @@ target_include_directories(umbra_test_insert_app_to_shadow.client PRIVATE add_drmf_test(umbra_client_scale_up_ptr_inline umbra_app umbra_client_scale_up_ptr_inline.c umbra "" "" ".*TEST PASSED") - use_DynamoRIO_extension(umbra_client_scale_up_ptr_inline.client drreg) - use_DynamoRIO_extension(umbra_client_scale_up_ptr_inline.client drutil) - target_include_directories(umbra_client_scale_up_ptr_inline.client PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}) +use_DynamoRIO_extension(umbra_client_scale_up_ptr_inline.client drreg) +use_DynamoRIO_extension(umbra_client_scale_up_ptr_inline.client drutil) +target_include_directories(umbra_client_scale_up_ptr_inline.client PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}) # Faulty redzones are only available on 32-bit. if (NOT X64) diff --git a/tests/framework/umbra_client_scale_up_ptr_inline.c b/tests/framework/umbra_client_scale_up_ptr_inline.c index eb6ac2cb8..bcb1c3f2f 100644 --- a/tests/framework/umbra_client_scale_up_ptr_inline.c +++ b/tests/framework/umbra_client_scale_up_ptr_inline.c @@ -66,7 +66,11 @@ static bool check_called = false; __FILE__, __LINE__, #cond, msg), dr_abort(), 0))) #define TEST(mask, var) (((mask) & (var)) != 0) +#ifdef X64 +#define SHDW_VAL (void *) 0x111111111111 +#else #define SHDW_VAL (void *) 0x11111111 +#endif DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) @@ -83,6 +87,9 @@ dr_client_main(client_id_t id, int argc, const char *argv[]) UMBRA_MAP_CREATE_SHADOW_ON_TOUCH | UMBRA_MAP_SHADOW_SHARED_READONLY; umbra_map_ops.default_value = 0; umbra_map_ops.default_value_size = 1; +# ifndef X64 + umbra_map_ops.make_redzone_faulty = false; +# endif if (umbra_init(id) != DRMF_SUCCESS) DR_ASSERT_MSG(false, "fail to init umbra"); if (umbra_create_mapping(&umbra_map_ops, &umbra_map) != DRMF_SUCCESS) @@ -107,7 +114,8 @@ static void check() // Read shadow value. void *data = NULL; size_t shdw_size = sizeof(void *); - status = umbra_read_shadow_memory(umbra_map, app_target, 1, &shdw_size, (void *) &data); + status = umbra_read_shadow_memory(umbra_map, app_target, 1, &shdw_size, + (void *) &data); CHECK(status == DRMF_SUCCESS, "Failed to read"); dr_fprintf(STDERR, "SIZES: %p %u %u\n", app_target, shdw_size, sizeof(void *)); CHECK(shdw_size == sizeof(void *), "read shadow size should be pointer-sized"); @@ -115,7 +123,8 @@ static void check() // Write NULL. data = NULL; - status = umbra_write_shadow_memory(umbra_map, app_target, 1, &shdw_size, (void *) &data); + status = umbra_write_shadow_memory(umbra_map, app_target, 1, &shdw_size, + (void *) &data); CHECK(status == DRMF_SUCCESS, "Failed to write"); CHECK(shdw_size == sizeof(void *), "write shadow size should be pointer-sized"); @@ -171,7 +180,8 @@ event_app_instruction(void *drcontext, void *tag, instrlist_t *ilist, instr_t *w drvector_delete(&allowed); # endif - succ = drutil_insert_get_mem_addr(drcontext, ilist, where, src_mem_opnd, scratch_reg, scratch_reg2); + succ = drutil_insert_get_mem_addr(drcontext, ilist, where, src_mem_opnd, + scratch_reg, scratch_reg2); DR_ASSERT(succ); /* Save the app address to a well-known spill slot, so that the fault handler @@ -179,18 +189,20 @@ event_app_instruction(void *drcontext, void *tag, instrlist_t *ilist, instr_t *w */ dr_save_reg(drcontext, ilist, where, scratch_reg, SPILL_SLOT_2); - drmf_status_t status = umbra_insert_app_to_shadow(drcontext, umbra_map, ilist, where, scratch_reg, &scratch_reg2, 1); + drmf_status_t status = umbra_insert_app_to_shadow(drcontext, umbra_map, ilist, + where, scratch_reg, + &scratch_reg2, 1); DR_ASSERT_MSG(status == DRMF_SUCCESS, "fail to insert translation"); instr_t *instr; // Load shadow value to reg. - opnd_t reg_opnd = opnd_create_reg(scratch_reg2); - opnd_t immed_opnd = opnd_create_immed_int((intptr_t) SHDW_VAL, OPSZ_PTR); - instr = XINST_CREATE_load_int(drcontext, reg_opnd, immed_opnd); - instrlist_meta_preinsert(ilist, where, instr); + opnd_t reg_opnd = opnd_create_reg(scratch_reg); + instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t) SHDW_VAL, reg_opnd, + ilist, where, NULL, NULL); - opnd_t shadow_opnd = opnd_create_base_disp(scratch_reg, DR_REG_NULL, 0, 0, OPSZ_PTR); + opnd_t shadow_opnd = opnd_create_base_disp(scratch_reg, DR_REG_NULL, 0, 0, + OPSZ_PTR); opnd_t src_opnd = opnd_create_reg(scratch_reg2); instr = XINST_CREATE_store(drcontext, shadow_opnd, src_opnd); instr_set_translation(instr, instr_get_app_pc(where)); @@ -199,8 +211,10 @@ event_app_instruction(void *drcontext, void *tag, instrlist_t *ilist, instr_t *w // Use a clean call to check write and refresh shadow value. dr_insert_clean_call(drcontext, ilist, where, check, false, 0); - if (drreg_unreserve_register(drcontext, ilist, where, scratch_reg) != DRREG_SUCCESS || - drreg_unreserve_register(drcontext, ilist, where, scratch_reg2) != DRREG_SUCCESS || + if (drreg_unreserve_register(drcontext, ilist, + where, scratch_reg) != DRREG_SUCCESS || + drreg_unreserve_register(drcontext, ilist, + where, scratch_reg2) != DRREG_SUCCESS || drreg_unreserve_aflags(drcontext, ilist, where) != DRREG_SUCCESS) DR_ASSERT(false); } From ceaf707dc516f7d333d85c9f011e8b625933c83d Mon Sep 17 00:00:00 2001 From: johnfxgalea Date: Sun, 31 Jan 2021 15:54:18 +0000 Subject: [PATCH 16/16] Fix bugs --- tests/framework/umbra_client_faulty_redzone.c | 2 +- .../umbra_client_scale_up_ptr_inline.c | 20 +++++++++---------- umbra/umbra_64.c | 3 +++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/framework/umbra_client_faulty_redzone.c b/tests/framework/umbra_client_faulty_redzone.c index 3cc9ff3bc..9a6dac6f4 100644 --- a/tests/framework/umbra_client_faulty_redzone.c +++ b/tests/framework/umbra_client_faulty_redzone.c @@ -1,5 +1,5 @@ /* ************************************************************** - * Copyright (c) 2020 Google, Inc. All rights reserved. + * Copyright (c) 2021 Google, Inc. All rights reserved. * **************************************************************/ /* diff --git a/tests/framework/umbra_client_scale_up_ptr_inline.c b/tests/framework/umbra_client_scale_up_ptr_inline.c index bcb1c3f2f..e00498002 100644 --- a/tests/framework/umbra_client_scale_up_ptr_inline.c +++ b/tests/framework/umbra_client_scale_up_ptr_inline.c @@ -1,5 +1,5 @@ /* ************************************************************** - * Copyright (c) 2017-2019 Google, Inc. All rights reserved. + * Copyright (c) 2021 Google, Inc. All rights reserved. * **************************************************************/ /* @@ -30,8 +30,9 @@ * DAMAGE. */ -/* Tests that there are no conflicts in any scale factor with the target - * application. +/* Tests Umbra's inline interface when using scaled up memory. In particular, + * we set up the scale such that every app byte is mapped to a pointer-sized + * shadow tag. */ #include #include @@ -116,16 +117,15 @@ static void check() size_t shdw_size = sizeof(void *); status = umbra_read_shadow_memory(umbra_map, app_target, 1, &shdw_size, (void *) &data); - CHECK(status == DRMF_SUCCESS, "Failed to read"); - dr_fprintf(STDERR, "SIZES: %p %u %u\n", app_target, shdw_size, sizeof(void *)); + CHECK(status == DRMF_SUCCESS, "failed to read"); CHECK(shdw_size == sizeof(void *), "read shadow size should be pointer-sized"); - CHECK(data == SHDW_VAL, "read shadow size should be pointer-sized"); + CHECK(data == SHDW_VAL, "read shadow value should match"); // Write NULL. data = NULL; status = umbra_write_shadow_memory(umbra_map, app_target, 1, &shdw_size, (void *) &data); - CHECK(status == DRMF_SUCCESS, "Failed to write"); + CHECK(status == DRMF_SUCCESS, "failed to write"); CHECK(shdw_size == sizeof(void *), "write shadow size should be pointer-sized"); // Set flag. @@ -194,17 +194,15 @@ event_app_instruction(void *drcontext, void *tag, instrlist_t *ilist, instr_t *w &scratch_reg2, 1); DR_ASSERT_MSG(status == DRMF_SUCCESS, "fail to insert translation"); - instr_t *instr; - // Load shadow value to reg. - opnd_t reg_opnd = opnd_create_reg(scratch_reg); + opnd_t reg_opnd = opnd_create_reg(scratch_reg2); instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t) SHDW_VAL, reg_opnd, ilist, where, NULL, NULL); opnd_t shadow_opnd = opnd_create_base_disp(scratch_reg, DR_REG_NULL, 0, 0, OPSZ_PTR); opnd_t src_opnd = opnd_create_reg(scratch_reg2); - instr = XINST_CREATE_store(drcontext, shadow_opnd, src_opnd); + instr_t *instr = XINST_CREATE_store(drcontext, shadow_opnd, src_opnd); instr_set_translation(instr, instr_get_app_pc(where)); instrlist_meta_preinsert(ilist, where, instr); diff --git a/umbra/umbra_64.c b/umbra/umbra_64.c index c2a43f79b..011b6d078 100644 --- a/umbra/umbra_64.c +++ b/umbra/umbra_64.c @@ -323,6 +323,7 @@ static ptr_uint_t map_disp[] = { /* These are for up through Win8. */ (WIN8_BASE_DISP)<<6, /* UMBRA_MAP_SCALE_DOWN_64X */ (WIN8_BASE_DISP)<<5, /* UMBRA_MAP_SCALE_DOWN_32X */ + (WIN8_BASE_DISP)<<4, /* UMBRA_MAP_SCALE_DOWN_16X */ (WIN8_BASE_DISP)<<3, /* UMBRA_MAP_SCALE_DOWN_8X */ (WIN8_BASE_DISP)<<2, /* UMBRA_MAP_SCALE_DOWN_4X */ (WIN8_BASE_DISP)<<1, /* UMBRA_MAP_SCALE_DOWN_2X */ @@ -333,6 +334,7 @@ static ptr_uint_t map_disp[] = { #else /* UNIX */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_64X */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_32X */ + 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_16X */ 0x0000900000000000, /* UMBRA_MAP_SCALE_DOWN_8X */ 0x0000440000000000, /* UMBRA_MAP_SCALE_DOWN_4X */ 0x0000220000000000, /* UMBRA_MAP_SCALE_DOWN_2X */ @@ -352,6 +354,7 @@ static ptr_uint_t map_disp[] = { static ptr_uint_t map_disp_win81[] = { (WIN81_BASE_DISP)<<6, /* UMBRA_MAP_SCALE_DOWN_64X */ (WIN81_BASE_DISP)<<5, /* UMBRA_MAP_SCALE_DOWN_32X */ + (WIN81_BASE_DISP)<<4, /* UMBRA_MAP_SCALE_DOWN_16X */ (WIN81_BASE_DISP)<<3, /* UMBRA_MAP_SCALE_DOWN_8X */ (WIN81_BASE_DISP)<<2, /* UMBRA_MAP_SCALE_DOWN_4X */ (WIN81_BASE_DISP_DOWN2)<<1, /* UMBRA_MAP_SCALE_DOWN_2X */