Initial commit
This commit is contained in:
commit
7d0aa69421
2
build.bat
Normal file
2
build.bat
Normal file
@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
cl main.cpp -Z7 -fsanitize=address -nologo -link || exit /b 1
|
182
main.cpp
Normal file
182
main.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
|
||||
#define WIN32_MEAN_AND_LEAN
|
||||
#include <Windows.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <sanitizer/asan_interface.h>
|
||||
|
||||
#define IsPowerOfTwo(value, pot) ((((size_t)value) & (((size_t)pot) - 1)) == 0)
|
||||
#define AsanAlignment 8
|
||||
|
||||
#define PrintByteSpacing(space) \
|
||||
if (index) \
|
||||
printf(space); \
|
||||
if (index && (index % 8 == 0)) \
|
||||
printf("| ")
|
||||
|
||||
static void PrintByteArray(char const *array, size_t array_size)
|
||||
{
|
||||
printf(" Byte Array ");
|
||||
for (size_t index = 0 ; index < array_size; index++) {
|
||||
PrintByteSpacing(" ");
|
||||
printf("%02zu", index);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void PrintPoisonedBytes(int step, char const *array, size_t array_size)
|
||||
{
|
||||
printf("%d. __asan_address_is_poisoned ", step);
|
||||
for (size_t index = 0 ; index < array_size; index++) {
|
||||
PrintByteSpacing(" ");
|
||||
printf("%c", __asan_address_is_poisoned(array + index) ? 'x' : ' ');
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void PrintPoisonMemoryIndex(int step, char const *array, size_t array_size, size_t poison_index)
|
||||
{
|
||||
printf("%d. __asan_poison_memory_region ", step);
|
||||
for (size_t index = 0; index < array_size; index++) {
|
||||
PrintByteSpacing(" ");
|
||||
printf("%c ", index == poison_index ? 'x' : ' ');
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void PrintPoisonMemoryRegion(int step, char const *array, size_t array_size, size_t poison_start_index, size_t poison_end_index)
|
||||
{
|
||||
printf("%d. __asan_poison_memory_region ", step);
|
||||
for (size_t index = 0; index < array_size; index++) {
|
||||
PrintByteSpacing(" ");
|
||||
printf("%c ", index >= poison_start_index && index <= poison_end_index ? 'x' : ' ');
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Here we demonstrate that ASAN poison-ing will only poison the\n"
|
||||
"byte region if the region meets an 8 byte boundary. It will only\n"
|
||||
"poison bytes upto the 8 byte boundary, any bytes that straddle\n"
|
||||
"the boundary that do not hit the next 8 byte boundary are not\n"
|
||||
"poison-ed.\n\n");
|
||||
|
||||
uint32_t const ASAN_ALIGNMENT = 8;
|
||||
uint32_t const REGION_WINDOW = 7;
|
||||
char array[16] = {};
|
||||
for (size_t poison_index = 0; poison_index < sizeof(array) - (REGION_WINDOW - 1); poison_index++) {
|
||||
assert(IsPowerOfTwo(array, ASAN_ALIGNMENT));
|
||||
|
||||
// NOTE: Print byte array ==================================================================
|
||||
|
||||
PrintByteArray(array, sizeof(array));
|
||||
|
||||
// NOTE: Poison the array ==================================================================
|
||||
|
||||
__asan_poison_memory_region(&array[poison_index], REGION_WINDOW);
|
||||
PrintPoisonMemoryRegion(1 /*step*/, array, sizeof(array), poison_index, poison_index + (REGION_WINDOW - 1));
|
||||
|
||||
// NOTE: Print the poison-ed bytes =========================================================
|
||||
|
||||
PrintPoisonedBytes(2 /*step*/, array, sizeof(array));
|
||||
|
||||
// NOTE: Cleanup ===========================================================================
|
||||
|
||||
__asan_unpoison_memory_region(array, sizeof(array));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf(
|
||||
"Now we demonstrate that unpoison-ing 1 byte in the 8 byte window\n"
|
||||
"will unpoison all bytes prior to it up until the start of the window\n"
|
||||
"until the previous 8 byte boundary.\n\n");
|
||||
|
||||
for (size_t unpoison_index = 0; unpoison_index < sizeof(array); unpoison_index++) {
|
||||
assert(IsPowerOfTwo(array, ASAN_ALIGNMENT));
|
||||
|
||||
// NOTE: Print byte array ==================================================================
|
||||
|
||||
PrintByteArray(array, sizeof(array));
|
||||
|
||||
// NOTE: Poison the array ==================================================================
|
||||
|
||||
__asan_poison_memory_region(array, sizeof(array));
|
||||
PrintPoisonMemoryRegion(1 /*step*/, array, sizeof(array), 0, sizeof(array) - 1);
|
||||
|
||||
// NOTE: Print the poison-ed bytes =========================================================
|
||||
|
||||
PrintPoisonedBytes(2 /*step*/, array, sizeof(array));
|
||||
|
||||
// NOTE: Unpoison byte at each position separately =========================================
|
||||
|
||||
printf("3. __asan_unpoison_memory_region ");
|
||||
__asan_unpoison_memory_region(array + unpoison_index, 1);
|
||||
|
||||
for (size_t index = 0 ; index < sizeof(array); index++) {
|
||||
PrintByteSpacing(" ");
|
||||
printf("%c", index == unpoison_index ? 'x' : ' ');
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// NOTE: Print the poison-ed bytes =========================================================
|
||||
|
||||
printf("4. __asan_address_is_poisoned ");
|
||||
for (size_t index = 0 ; index < sizeof(array); index++) {
|
||||
PrintByteSpacing(" ");
|
||||
printf("%c", __asan_address_is_poisoned(array + index) ? 'x' : ' ');
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
// NOTE: Cleanup ===========================================================================
|
||||
|
||||
__asan_unpoison_memory_region(array, sizeof(array));
|
||||
}
|
||||
|
||||
printf(
|
||||
"Unpoison-ing across 8 byte boundaries may lead to undesired\n"
|
||||
"behaviour, with all bytes on the left side of the boundary being\n"
|
||||
"unpoisoned\n\n");
|
||||
{
|
||||
// NOTE: Print byte array ==================================================================
|
||||
|
||||
char array[16] = {};
|
||||
PrintByteArray(array, sizeof(array));
|
||||
|
||||
// NOTE: Poison the array ==================================================================
|
||||
|
||||
__asan_poison_memory_region(array, sizeof(array));
|
||||
PrintPoisonMemoryRegion(1 /*step*/, array, sizeof(array), 0, sizeof(array) - 1);
|
||||
|
||||
// NOTE: Print the poison-ed bytes =========================================================
|
||||
|
||||
PrintPoisonedBytes(2 /*step*/, array, sizeof(array));
|
||||
|
||||
// NOTE: Unpoison across the 8 byte boundary ===============================================
|
||||
|
||||
printf("3. __asan_unpoison_memory_region ");
|
||||
uint32_t const start_poison_index = 7;
|
||||
uint32_t const bytes_to_unpoison = 2;
|
||||
uint32_t const end_poison_index = start_poison_index + (bytes_to_unpoison - 1);
|
||||
__asan_unpoison_memory_region(array + start_poison_index, bytes_to_unpoison);
|
||||
|
||||
for (size_t index = 0 ; index < sizeof(array); index++) {
|
||||
PrintByteSpacing(" ");
|
||||
printf("%c", index >= start_poison_index && index <= end_poison_index ? 'x' : ' ');
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// NOTE: Print the poison-ed bytes =========================================================
|
||||
|
||||
PrintPoisonedBytes(4 /*step*/, array, sizeof(array));
|
||||
}
|
||||
|
||||
printf("\n\nTLDR:\n"
|
||||
" __asan_poison_memory_region(ptr, size)\n"
|
||||
" Poisons the byte region [ptr, AlignDown(ptr+size, 8))\n\n"
|
||||
" __asan_unpoison_memory_region(ptr, size)\n"
|
||||
" Unpoisons the byte region [AlignDown(ptr, 8), ptr+size)\n\n"
|
||||
);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user