static void * _get_address(unsigned char null_allowed) { void *addr = NULL; int i; /* Because we get called during startup when we create fd's, we need * to special case this, as we can't use get_non_null_address at that point */ if (getpid() == shm->mainpid) return page_rand; if (null_allowed == TRUE) i = rand() % 4; else i = rand_range(1, 3); switch (i) { case 0: addr = NULL; break; case 1: addr = (void *) KERNEL_ADDR; break; case 2: addr = (void *)(unsigned long)rand64(); break; case 3: addr = get_writable_address(page_size); break; } return addr; }
static void bpf_prog_load(union bpf_attr *attr) { unsigned long *insns = NULL, len = 0; attr->prog_type = RAND_ARRAY(bpf_prog_types); switch (attr->prog_type) { case BPF_PROG_TYPE_SOCKET_FILTER: bpf_gen_filter(&insns, &len); break; default: // this will go away when all the other cases are enumerated insns = zmalloc(page_size); generate_rand_bytes((unsigned char *)insns, len); break; } attr->insn_cnt = len; attr->insns = (u64) insns; attr->license = (u64) license; attr->log_level = 0; attr->log_size = rnd() % page_size; attr->log_buf = (u64) get_writable_address(page_size); attr->kern_version = rnd(); // TODO: stick uname in here. }
static unsigned long random_ioctl_arg(void) { if (RAND_BOOL()) { return (unsigned long) rand64(); } else { void *page; page = get_writable_address(page_size); generate_random_page(page); return (unsigned long) page; } }
static void dm_sanitise(const struct ioctl_group *grp, struct syscallrecord *rec) { struct dm_ioctl *dm; pick_random_ioctl(grp, rec); rec->a3 = (unsigned long) get_writable_address(sizeof(struct dm_ioctl)); dm = (struct dm_ioctl *) rec->a3; /* set a sensible version to get past the initial checks */ dm->version[0] = DM_VERSION_MAJOR; dm->version[1] = DM_VERSION_MINOR; dm->version[2] = DM_VERSION_PATCHLEVEL; /* clear one of these strings to pass some kernel validation */ if (RAND_BOOL()) dm->name[0] = 0; else dm->uuid[0] = 0; }
static unsigned long fill_arg(struct syscallrecord *rec, unsigned int argnum) { struct syscallentry *entry; unsigned int call; enum argtype argtype; call = rec->nr; entry = syscalls[call].entry; if (argnum > entry->num_args) return 0; argtype = get_argtype(entry, argnum); switch (argtype) { case ARG_UNDEFINED: if (RAND_BOOL()) return (unsigned long) rand64(); return (unsigned long) get_writable_address(page_size); case ARG_FD: if (RAND_BOOL()) { unsigned int i; /* If this is the 2nd or more ARG_FD, make it unique */ for (i = 0; i < argnum; i++) { enum argtype arg; arg = get_argtype(entry, i); if (arg == ARG_FD) return get_new_random_fd(); } } return get_random_fd(); case ARG_LEN: return (unsigned long) get_len(); case ARG_ADDRESS: return handle_arg_address(rec, argnum); case ARG_NON_NULL_ADDRESS: return (unsigned long) get_non_null_address(); case ARG_MMAP: return (unsigned long) get_map(); case ARG_PID: return (unsigned long) get_pid(); case ARG_RANGE: return handle_arg_range(entry, argnum); case ARG_OP: /* Like ARG_LIST, but just a single value. */ return handle_arg_op(entry, argnum); case ARG_LIST: return handle_arg_list(entry, argnum); case ARG_CPU: return (unsigned long) get_cpu(); case ARG_PATHNAME: return (unsigned long) generate_pathname(); case ARG_IOVEC: return handle_arg_iovec(entry, rec, argnum); case ARG_IOVECLEN: case ARG_SOCKADDRLEN: /* We already set the len in the ARG_IOVEC/ARG_SOCKADDR case * So here we just return what we had set there. */ return get_argval(rec, argnum); case ARG_SOCKADDR: return handle_arg_sockaddr(entry, rec, argnum); case ARG_MODE_T: return handle_arg_mode_t(); case ARG_SOCKETINFO: return (unsigned long) get_rand_socketinfo(); } BUG("unreachable!\n"); }