fix bad cut-n-paste causing inverted state when using -r on uniarch
[trinity.git] / random-address.c
blob52c5366a5fe460e8e1b17374cb8ded087d97df52
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <sys/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"
14 #include "tables.h"
17 static bool within_page(void *addr, void *check)
19 if (addr == check)
20 return TRUE;
21 if ((addr > check) && (addr < (check + page_size)))
22 return TRUE;
23 return FALSE;
26 bool validate_address(void *addr)
28 if (within_page(addr, shm) == TRUE)
29 return FALSE;
30 if (within_page(addr, page_rand) == TRUE)
31 return FALSE;
32 if (within_page(addr, page_zeros) == TRUE)
33 return FALSE;
34 if (within_page(addr, page_0xff) == TRUE)
35 return FALSE;
36 if (within_page(addr, page_allocs) == TRUE)
37 return FALSE;
39 return TRUE;
43 static void * _get_address(unsigned char null_allowed)
45 int i;
46 void *addr = NULL;
48 if (null_allowed == TRUE)
49 i = rand() % 9;
50 else
51 i = (rand() % 8) + 1;
54 switch (i) {
55 case 0: addr = NULL;
56 break;
57 case 1: addr = (void *) KERNEL_ADDR;
58 break;
59 case 2: addr = page_zeros;
60 break;
61 case 3: addr = page_0xff;
62 break;
63 case 4: addr = page_rand;
64 break;
65 case 5: addr = page_allocs;
66 break;
67 case 6: addr = (void *)(unsigned long)rand64();
68 break;
69 case 7: addr = get_map();
70 break;
71 case 8: addr = malloc(page_size * 2);
72 // FIXME: We leak this. This is the address we need to store for later
73 // freeing, not the potentially munged version below.
74 // tricky. We want to hand the munged version out too, so we might end up
75 // having to split this into alloc_address / get_address.
76 break;
77 default:
78 BUG("unreachable!\n");
79 break;
83 * Most of the time, we just return the address we got above unmunged.
84 * But sometimes, we return an address just before the end of the page.
85 * The idea here is that we might see some bugs that are caused by page boundary failures.
87 i = rand() % 100;
88 switch (i) {
89 case 0: addr += (page_size - sizeof(char));
90 break;
91 case 1: addr += (page_size - sizeof(int));
92 break;
93 case 2: addr += (page_size - sizeof(long));
94 break;
95 case 3: addr += (page_size / 2);
96 break;
97 case 4 ... 99:
98 default: break;
101 return addr;
104 void * get_address(void)
106 return _get_address(TRUE);
109 void * get_non_null_address(void)
111 return _get_address(FALSE);
115 unsigned long find_previous_arg_address(unsigned int argnum, unsigned int call, int childno)
117 unsigned long addr = 0;
119 if (argnum > 1)
120 if ((syscalls[call].entry->arg1type == ARG_ADDRESS) ||
121 (syscalls[call].entry->arg1type == ARG_NON_NULL_ADDRESS))
122 addr = shm->a1[childno];
124 if (argnum > 2)
125 if ((syscalls[call].entry->arg2type == ARG_ADDRESS) ||
126 (syscalls[call].entry->arg2type == ARG_NON_NULL_ADDRESS))
127 addr = shm->a2[childno];
129 if (argnum > 3)
130 if ((syscalls[call].entry->arg3type == ARG_ADDRESS) ||
131 (syscalls[call].entry->arg3type == ARG_NON_NULL_ADDRESS))
132 addr = shm->a3[childno];
134 if (argnum > 4)
135 if ((syscalls[call].entry->arg4type == ARG_ADDRESS) ||
136 (syscalls[call].entry->arg4type == ARG_NON_NULL_ADDRESS))
137 addr = shm->a4[childno];
139 if (argnum > 5)
140 if ((syscalls[call].entry->arg5type == ARG_ADDRESS) ||
141 (syscalls[call].entry->arg5type == ARG_NON_NULL_ADDRESS))
142 addr = shm->a5[childno];
144 return addr;
149 * iovec's are just special cases of the ARG_ADDRESS's
151 struct iovec * alloc_iovec(unsigned int num)
153 struct iovec *iov;
154 unsigned int i;
156 iov = malloc(num * sizeof(struct iovec));
157 if (iov != NULL) {
158 for (i = 0; i < num; i++) {
159 iov[i].iov_base = malloc(page_size);
160 iov[i].iov_len = page_size;
163 return iov;