aboutsummaryrefslogtreecommitdiff
blob: 14c64771d6515918721639f83bad127b5f78314d (plain)
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;
}