Я пишу блок-тест для моей библиотеки обработки UTF8, и я хочу, чтобы мой тест был segfault, если функция переходит в переполнение буфера. Поэтому я придумал идею объединить две страницы рядом друг с другом в памяти, первая с PROT_READ | PROT_WRITE, а второй с PROT_NONE. Таким образом, если произойдет переполнение, гарантируется segfault. Вот пример:mmaping две последовательные страницы
void *addr1, *addr2; /* these are the pages; mmap call left out for simplicity */
char *p = (char *) (addr1 + getpagesize() - 8);
utf8_encode(aUtf8String, p, 8); // this shouldn't segfault
Проблема заключается в том, когда я отобразить вторую страницу, моя программа возвращает ошибку сегментации. Вот пример программы, которая воспроизводит эту проблему (GNU/Linux):
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
void checkMap(void *p)
{
if(p == MAP_FAILED) {
printf("error running mmap: %s\n", strerror(errno));
exit(1);
}
}
int main(void)
{
void *addr1, *addr2;
size_t pagesize;
pagesize = getpagesize();
checkMap(addr1 = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
checkMap(addr2 = mmap(addr1 + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)); /* segfaults */
munmap(addr1, pagesize);
munmap(addr2, pagesize);
return 0;
}
достаточно Интересно, что Е() заявление перед первым ттар() заставляет программу успешно работать. Кто-нибудь знает, почему mmap является segfaulting? Если моя цель недостижима с помощью mmap(), есть ли у кого-нибудь другие советы о том, как я могу проверить свой код на переполнение буфера?
Ваш код отлично работает для меня. Единственное, что вы не включаете unistd.h для getpagesize(). Компилятор угадает тип. Это может привести к проблемам на 64-битных системах, я думаю, если угадать 32-битный int. –
Я тоже тестировал его, и я получаю segfault, но не внутри main(). Скорее, он падает в коде glibc, на выходе ... Действительно странно, это одно. Я тестировал на очень простой 32-битной машине. – unwind
Любопытно, в какой версии ядра/дистрибутива вы запускаете его? Я просто попробовал это на 64-битном (после #including unistd.h), и теперь он терпит неудачу в munmap. – 2009-02-27 16:54:58