提交 3748cf9e 编写于 作者: F Far

fix: malloc指针混淆及safe-unlink测试用例优化

在32位情况下,由于pretrim的存在,可能导致原用例无法正常进入unbin路径,
进而引起子进程未能按照预期终止。通过更加精细地控制流程及增加malloc次数,
保证进入unbin分支。
malloc-free-performance由于需要打印耗时调用t_printf导致t_status修改为1,
实际无错误,因此避免误报,直接返回0。
Signed-off-by: NFar <yesiyuan2@huawei.com>
Change-Id: I810b7f0b032deed33871e73b4bc428ac3ad13eb8
上级 71953afd
......@@ -190,5 +190,5 @@ int main(int argc, char *argv[])
t_printf("Malloc and free %d times cost %lf s\n", MALLOC_TIME, cost / NANOSEC_PER_SEC);
return t_status;
return 0;
}
......@@ -25,20 +25,43 @@ static void handler(int s)
{
}
volatile uintptr_t *p0;
volatile uintptr_t *p1;
volatile void *tmp;
static int child(void)
{
uintptr_t *p = (uintptr_t *)malloc(10 * sizeof(uintptr_t));
if (!p) {
p0 = (uintptr_t *)malloc(10 * sizeof(uintptr_t));
if (!p0) {
t_error("Malloc failed:%s\n", strerror(errno));
return -1;
}
/* Malloc a dividing chunk to avoid combination of neighbouring freed chunk */
tmp = malloc(10 * sizeof(uintptr_t));
/* Malloc another chunk to get a key */
p1 = (uintptr_t *)malloc(10 * sizeof(uintptr_t));
if (!p1) {
t_error("Malloc failed:%s\n", strerror(errno));
return -1;
}
/* Malloc a dividing chunk to avoid combination of neighbouring freed chunk */
malloc(10 * sizeof(uintptr_t));
free(p);
/* Reverse the pointer getting an illegal pointer */
*p = ~*p;
/* Malloc same chunk to trigger illegal pointer access */
p = (uintptr_t *)malloc(10 *sizeof(uintptr_t));
tmp = malloc(10 * sizeof(uintptr_t));
free((void *)p0);
free((void *)p1);
uintptr_t *fake_ptr = (uintptr_t *)((uintptr_t)((char *)p1 - sizeof(size_t) * 2) ^ (uintptr_t)p0[0]);
p0[0] = (uintptr_t)fake_ptr;
p1[0] = (uintptr_t)fake_ptr;
/*
* The init procedure makes the freelist unpredictable. To make sure to trigger the ivalid ptr
* acess, here we create as many chunks as possible to make sure there are enough chunks in
* bin[j] of size "10 * sizeof(uintptr_t)". Basically this is heap spray.
*/
for (int i = 0; i < 512; ++i) {
tmp = malloc(10 *sizeof(uintptr_t));
}
return 0;
}
......@@ -91,12 +114,12 @@ int main(int argc, char *argv[])
}
if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGSEGV) {
if (WTERMSIG(status) != SIGSEGV && WTERMSIG(status) != SIGILL) {
t_error("%s child process out with %s\n", argv[0], strsignal(WTERMSIG(status)));
return -1;
}
} else {
t_error("%s child process finished normally\n", argv[0]);
}
return t_status;
return 0;
}
......@@ -25,37 +25,46 @@ static void handler(int s)
{
}
static int child(void)
volatile void *tmp;
int set_devide_chunk(size_t size)
{
uintptr_t *c0 = (uintptr_t *)malloc(sizeof(uintptr_t) * 10);
if (!c0) {
t_error("Malloc failed: %s\n", strerror(errno));
return -1;
}
/* Malloc a dividing chunk to avoiding combination of neighbouring chunk */
malloc(sizeof(uintptr_t) * 10);
/* Malloc another chunk */
uintptr_t *c1 = (uintptr_t *)malloc(sizeof(uintptr_t) * 10);
if (!c1) {
if (!(tmp = malloc(size))) {
t_error("Malloc failed: %s\n", strerror(errno));
return -1;
}
/* Malloc a dividing chunk to avoiding combination of neighbouring chunk */
malloc(sizeof(uintptr_t) * 10);
return 0;
}
static int child(void)
{
uintptr_t *c;
uintptr_t *temp;
/* Free the chunk, now they are in same list */
free(c0);
free(c1);
/* Set first dividing chunk */
if (set_devide_chunk(sizeof(size_t)))
return -1;
/* Exchange the next and prev pointer in chunk */
/* They are legal but wrongly pointing */
uintptr_t temp = c0[0];
c0[0] = c0[1];
c0[1] = temp;
/*
* The init procedure makes the freelist unpredictable. To make sure trigger the safe-unlink
* check, Here we create as many chunks as possible to make sure there are enough chunks in
* bin[0] and malloc again. Basically this is heap spray.
*/
for (int i = 0; i < 512; ++i) {
if (set_devide_chunk(sizeof(size_t)))
return -1;
c = (uintptr_t *)malloc(sizeof(uintptr_t));
if (!c) {
t_error("Malloc failed: %s\n", strerror(errno));
return -1;
}
free(c);
/* exchange the prev and next pointer */
uintptr_t temp = c[0];
c[0] = c[1];
c[1] = temp;
}
/* Malloc again, trigger the safe-unlink check */
c0 = (uintptr_t *)malloc(sizeof(uintptr_t) * 10);
c1 = (uintptr_t *)malloc(sizeof(uintptr_t) * 10);
return 0;
}
......@@ -108,12 +117,12 @@ int main(int argc, char *argv[])
}
if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGSEGV) {
if (WTERMSIG(status) != SIGSEGV && WTERMSIG(status) != SIGILL) {
t_error("%s child process out with %s\n", argv[0], strsignal(WTERMSIG(status)));
return -1;
}
} else {
t_error("%s child process finished normally\n", argv[0]);
}
return t_status;
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册