unsigned long get_interesting_value(void) { #if __WORDSIZE == 32 return get_interesting_32bit_value(); #else unsigned long low = 0; if (rand_bool()) low = get_interesting_32bit_value(); switch (rand() % 13) { case 0: return 0; case 1: return low; case 2: return 0x0000000100000000UL | low; case 3: return 0x7fffffff00000000UL | low; case 4: return 0x8000000000000000UL | low; case 5: return 0xffffffff00000000UL | low; case 6: return 0xffffffffffffff00UL | (rand() % 256); case 7: return 0xffffffffffffffffUL - page_size; case 8: return PAGE_OFFSET | (low << 4); case 9: return KERNEL_ADDR | (low & 0xffffff); case 10: return MODULE_ADDR | (low & 0xffffff); case 11: return per_arch_interesting_addr(low); case 12: return (low << 32); } return low; // unreachable, but gcc is dumb. #endif /* __WORDSIZE */ }
unsigned long get_interesting_value(void) { unsigned long low = 0; switch (rand() % 3) { case 0: low = get_interesting_8bit_value(); break; case 1: low = get_interesting_16bit_value(); break; case 2: low = get_interesting_32bit_value(); break; } low = (rand() & 0xf) ? low : plus_minus_two(low); // 1 in 16 call plus_minus_two #if __WORDSIZE != 32 if (RAND_BOOL()) { // FIXME: This should likely be less aggressive than 50/50 switch (rand() % 11) { case 0: return 0x0000000100000000UL | low; case 1: return 0x7fffffff00000000UL | low; case 2: return 0x8000000000000000UL | low; case 3: return 0xffffffff00000000UL | low; case 4: return 0xffffffffffffff00UL | RAND_BYTE(); case 5: return 0xffffffffffffffffUL - page_size; case 6: return PAGE_OFFSET | (low << 4); case 7: return KERNEL_ADDR | (low & 0xffffff); case 8: return MODULE_ADDR | (low & 0xffffff); case 9: return per_arch_interesting_addr(low); case 10: return (low << 32); } } #endif /* __WORDSIZE */ return low; }
static void sanitise_getrlimit(int childno) { if (rand() % 2 == 0) return; /* set "resource" some random value half the time. */ shm->a1[childno] = get_interesting_32bit_value(); }
/* * "selector" function for 32bit random. * only called from rand32() */ static unsigned int __rand32(void) { unsigned long r = 0; switch (rand() % 7) { case 0: r = rand_single_bit(32); break; case 1: r = randbits(32); break; case 2: r = rand(); break; case 3: r = taviso(); break; case 4: r = rand8x8(); break; case 5: r = rept8(4); break; case 6: return get_interesting_32bit_value(); } return r; }
static void fabricate_onepage_struct(char *page) { unsigned int i; void **ptr; for (i = 0; i < page_size; ) { ptr = (void*)&page[i]; switch (rand() % 4) { case 0: i += sizeof(unsigned int); if (i > page_size) return; *(unsigned int *)ptr = get_interesting_32bit_value(); break; case 1: i += sizeof(unsigned long); if (i > page_size) return; *(unsigned long *)ptr = get_interesting_value(); break; case 2: i += sizeof(void *); if (i > page_size) return; *ptr = get_address(); break; case 3: i += sizeof(unsigned int); if (i > page_size) return; *(unsigned int *)ptr = rand() % page_size; break; default: BUG("unreachable!\n"); return; } } }