diff options
Diffstat (limited to 'tools/testing/selftests/x86/test_shadow_stack.c')
| -rw-r--r-- | tools/testing/selftests/x86/test_shadow_stack.c | 67 | 
1 files changed, 63 insertions, 4 deletions
diff --git a/tools/testing/selftests/x86/test_shadow_stack.c b/tools/testing/selftests/x86/test_shadow_stack.c index 757e6527f67e..ee909a7927f9 100644 --- a/tools/testing/selftests/x86/test_shadow_stack.c +++ b/tools/testing/selftests/x86/test_shadow_stack.c @@ -556,7 +556,7 @@ struct node {   *      looked at the shadow stack gaps.   *   5. See if it landed in the gap.   */ -int test_guard_gap(void) +int test_guard_gap_other_gaps(void)  {  	void *free_area, *shstk, *test_map = (void *)0xFFFFFFFFFFFFFFFF;  	struct node *head = NULL, *cur; @@ -593,11 +593,64 @@ int test_guard_gap(void)  	if (shstk - test_map - PAGE_SIZE != PAGE_SIZE)  		return 1; -	printf("[OK]\tGuard gap test\n"); +	printf("[OK]\tGuard gap test, other mapping's gaps\n");  	return 0;  } +/* Tests respecting the guard gap of the mapping getting placed */ +int test_guard_gap_new_mappings_gaps(void) +{ +	void *free_area, *shstk_start, *test_map = (void *)0xFFFFFFFFFFFFFFFF; +	struct node *head = NULL, *cur; +	int ret = 0; + +	free_area = mmap(0, PAGE_SIZE * 4, PROT_READ | PROT_WRITE, +			 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +	munmap(free_area, PAGE_SIZE * 4); + +	/* Test letting map_shadow_stack find a free space */ +	shstk_start = mmap(free_area, PAGE_SIZE, PROT_READ | PROT_WRITE, +			   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +	if (shstk_start == MAP_FAILED || shstk_start != free_area) +		return 1; + +	while (test_map > shstk_start) { +		test_map = (void *)syscall(__NR_map_shadow_stack, 0, PAGE_SIZE, 0); +		if (test_map == MAP_FAILED) { +			printf("[INFO]\tmap_shadow_stack MAP_FAILED\n"); +			ret = 1; +			break; +		} + +		cur = malloc(sizeof(*cur)); +		cur->mapping = test_map; + +		cur->next = head; +		head = cur; + +		if (test_map == free_area + PAGE_SIZE) { +			printf("[INFO]\tNew mapping has other mapping in guard gap!\n"); +			ret = 1; +			break; +		} +	} + +	while (head) { +		cur = head; +		head = cur->next; +		munmap(cur->mapping, PAGE_SIZE); +		free(cur); +	} + +	munmap(shstk_start, PAGE_SIZE); + +	if (!ret) +		printf("[OK]\tGuard gap test, placement mapping's gaps\n"); + +	return ret; +} +  /*   * Too complicated to pull it out of the 32 bit header, but also get the   * 64 bit one needed above. Just define a copy here. @@ -850,9 +903,15 @@ int main(int argc, char *argv[])  		goto out;  	} -	if (test_guard_gap()) { +	if (test_guard_gap_other_gaps()) { +		ret = 1; +		printf("[FAIL]\tGuard gap test, other mappings' gaps\n"); +		goto out; +	} + +	if (test_guard_gap_new_mappings_gaps()) {  		ret = 1; -		printf("[FAIL]\tGuard gap test\n"); +		printf("[FAIL]\tGuard gap test, placement mapping's gaps\n");  		goto out;  	}  |