1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/*
* Make sure the process_vm_readv func can work with strings with different
* alignments and lengths.
*
* https://bugs.gentoo.org/560396
*/
/* We want to make some bad calls. */
#undef _FORTIFY_SOURCES
#include "tests.h"
/* Make sure the buffer spans multiple pages. */
#define SIZE 0x1000
/* Make sure the buffer has plenty of slack space before/after. */
static char buf[SIZE * 8];
/* The smaller the span, the # of calls goes up: O(N*N*2+N). */
#define COUNT 0x20
#define STRIDE (SIZE / COUNT)
/* Some hacks to defeat gcc warnings so we can use bad pointers. */
volatile uintptr_t offset = 0;
#define non_const_ptr(ptr) ((void *)((uintptr_t)(ptr) + offset))
#define check_ptr(addr) \
({ \
printf(" open(%p)\n", addr); \
ret = open(non_const_ptr(addr), O_RDONLY); \
assert(ret == -1 && errno == EFAULT); \
})
int main(int argc, char *argv[])
{
int ret;
char *path = PTR_ALIGN_UP((char *)buf, SIZE);
size_t start, end;
setbuf(stdout, NULL);
printf("some bad pointers\n");
check_ptr(NULL);
check_ptr((void *)-1);
printf("lots of good pointers\n");
printf(" buf = %p\n", buf);
printf(" path = %p\n", path);
for (start = 0; start < SIZE * 2 + STRIDE; start += STRIDE) {
char *p = path + start;
for (end = start + STRIDE; end < SIZE * 2 + STRIDE; end += STRIDE) {
size_t len = end - start;
printf(" open(%p -> %p [+%#zx])\n", p, p + len, len);
memset(p, 'a', len);
path[end] = '\0';
ret = open(p, O_RDONLY);
assert(ret == -1 && (errno == ENOENT || errno == ENAMETOOLONG));
}
}
return 0;
}
|