split init_syscalls into uni/biarch
[trinity.git] / random-address.c
blob49ada0f85e46677721829f402e46f5a713e6dcd9
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <linux/uio.h>
7 #include "trinity.h" // page_size
8 #include "arch.h" // KERNEL_ADDR etc
9 #include "log.h"
10 #include "random.h"
11 #include "sanitise.h"
12 #include "maps.h"
13 #include "shm.h"
16 static bool within_page(void *addr, void *check)
18 if (addr == check)
19 return TRUE;
20 if ((addr > check) && (addr < (check + page_size)))
21 return TRUE;
22 return FALSE;
25 bool validate_address(void *addr)
27 if (within_page(addr, shm) == TRUE)
28 return FALSE;
29 if (within_page(addr, page_rand) == TRUE)
30 return FALSE;
31 if (within_page(addr, page_zeros) == TRUE)
32 return FALSE;
33 if (within_page(addr, page_0xff) == TRUE)
34 return FALSE;
35 if (within_page(addr, page_allocs) == TRUE)
36 return FALSE;
38 return TRUE;
42 static void * _get_address(unsigned char null_allowed)
44 int i;
45 void *addr = NULL;
47 if (null_allowed == TRUE)
48 i = rand() % 9;
49 else
50 i = (rand() % 8) + 1;
53 switch (i) {
54 case 0: addr = NULL;
55 break;
56 case 1: addr = (void *) KERNEL_ADDR;
57 break;
58 case 2: addr = page_zeros;
59 break;
60 case 3: addr = page_0xff;
61 break;
62 case 4: addr = page_rand;
63 break;
64 case 5: addr = page_allocs;
65 break;
66 case 6: addr = (void *)(unsigned long)rand64();
67 break;
68 case 7: addr = get_map();
69 break;
70 case 8: addr = malloc(page_size * 2);
71 // FIXME: We leak this. This is the address we need to store for later
72 // freeing, not the potentially munged version below.
73 // tricky. We want to hand the munged version out too, so we might end up
74 // having to split this into alloc_address / get_address.
75 break;
76 default:
77 BUG("unreachable!\n");
78 break;
82 * Most of the time, we just return the address we got above unmunged.
83 * But sometimes, we return an address just before the end of the page.
84 * The idea here is that we might see some bugs that are caused by page boundary failures.
86 i = rand() % 100;
87 switch (i) {
88 case 0: addr += (page_size - sizeof(char));
89 break;
90 case 1: addr += (page_size - sizeof(int));
91 break;
92 case 2: addr += (page_size - sizeof(long));
93 break;
94 case 3: addr += (page_size / 2);
95 break;
96 case 4 ... 99:
97 default: break;
100 return addr;
103 void * get_address(void)
105 return _get_address(TRUE);
108 void * get_non_null_address(void)
110 return _get_address(FALSE);
114 unsigned long find_previous_arg_address(unsigned int argnum, unsigned int call, int childno)
116 unsigned long addr = 0;
118 if (argnum > 1)
119 if ((syscalls[call].entry->arg1type == ARG_ADDRESS) ||
120 (syscalls[call].entry->arg1type == ARG_NON_NULL_ADDRESS))
121 addr = shm->a1[childno];
123 if (argnum > 2)
124 if ((syscalls[call].entry->arg2type == ARG_ADDRESS) ||
125 (syscalls[call].entry->arg2type == ARG_NON_NULL_ADDRESS))
126 addr = shm->a2[childno];
128 if (argnum > 3)
129 if ((syscalls[call].entry->arg3type == ARG_ADDRESS) ||
130 (syscalls[call].entry->arg3type == ARG_NON_NULL_ADDRESS))
131 addr = shm->a3[childno];
133 if (argnum > 4)
134 if ((syscalls[call].entry->arg4type == ARG_ADDRESS) ||
135 (syscalls[call].entry->arg4type == ARG_NON_NULL_ADDRESS))
136 addr = shm->a4[childno];
138 if (argnum > 5)
139 if ((syscalls[call].entry->arg5type == ARG_ADDRESS) ||
140 (syscalls[call].entry->arg5type == ARG_NON_NULL_ADDRESS))
141 addr = shm->a5[childno];
143 return addr;
148 * iovec's are just special cases of the ARG_ADDRESS's
150 struct iovec * alloc_iovec(unsigned int num)
152 struct iovec *iov;
153 unsigned int i;
155 iov = malloc(num * sizeof(struct iovec));
156 if (iov != NULL) {
157 for (i = 0; i < num; i++) {
158 iov[i].iov_base = malloc(page_size);
159 iov[i].iov_len = page_size;
162 return iov;