int get_random_dynamic_subclass( int cl ) {/* Init get_random_dynamic_subclass */ int random_object; random_object = get_random_object(cl); return(get_dynamic_from_object(cl,random_object)); }/* End get_random_dynamic_subclass */
/* * Return a pointer a previous mmap() that we did, either during startup, * or from a fuzz result. */ struct map * get_map(void) { struct object *obj = NULL; struct childdata *child = this_child(); bool global; enum objecttype type = 0; /* * Some of the fd providers need weird mappings on startup. * (fd-perf for eg), these are called from the main process, * and hence don't have a valid this_child, so we address the * initial mappings list directly. */ if (child == NULL) global = OBJ_GLOBAL; else global = OBJ_LOCAL; while (obj == NULL) { switch (rnd() % 3) { case 0: type = OBJ_MMAP_ANON; break; case 1: type = OBJ_MMAP_FILE; break; case 2: type = OBJ_MMAP_TESTFILE; break; } obj = get_random_object(type, global); } return &obj->map; }
int get_rand_pipe_fd(void) { struct object *obj; obj = get_random_object(OBJ_FD_PIPE, OBJ_GLOBAL); return obj->pipefd; }
static int get_rand_file_fd(void) { struct object *obj; if (no_objects(OBJ_FD_FILE) == TRUE) return -1; obj = get_random_object(OBJ_FD_FILE, OBJ_GLOBAL); return obj->filefd; }
static int get_rand_fanotifyfd(void) { struct object *obj; /* check if eventfd unavailable/disabled. */ if (objects_empty(OBJ_FD_FANOTIFY) == TRUE) return -1; obj = get_random_object(OBJ_FD_FANOTIFY, OBJ_GLOBAL); return obj->fanotifyfd; }
static int get_rand_memfd_fd(void) { struct object *obj; /* check if eventfd unavailable/disabled. */ if (objects_empty(OBJ_FD_MEMFD) == TRUE) return -1; obj = get_random_object(OBJ_FD_MEMFD, OBJ_GLOBAL); return obj->memfd; }
int get_rand_perf_fd(void) { struct object *obj; /* check if perf unavailable/disabled. */ if (objects_empty(OBJ_FD_PERF) == TRUE) return -1; obj = get_random_object(OBJ_FD_PERF, OBJ_GLOBAL); return obj->perffd; }
/* * Return a pointer a previous mmap() that we did, either during startup, * or from a fuzz result. */ struct map * get_map(void) { struct object *obj; struct map *map; bool global; /* * Some of the fd providers need weird mappings on startup. * (fd-perf for eg), these are called from the main process, * and hence don't have a valid this_child, so we address the * initial mappings list directly. */ if (this_child == NULL) global = OBJ_GLOBAL; else global = OBJ_LOCAL; obj = get_random_object(OBJ_MMAP, global); map = &obj->map; return map; }
static void socket_destructor(struct object *obj) { struct socketinfo *si = &obj->sockinfo; struct linger ling = { .l_onoff = FALSE, .l_linger = 0 }; int fd; //FIXME: This is a workaround for a weird bug where we hang forevre // waiting for bluetooth sockets when we setsockopt. // Hopefully at some point we can remove this when someone figures out what's going on. if (si->triplet.family == PF_BLUETOOTH) return; /* Grab an fd, and nuke it before someone else uses it. */ fd = si->fd; si->fd = 0; /* disable linger */ (void) setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)); (void) shutdown(fd, SHUT_RDWR); if (close(fd) != 0) output(1, "failed to close socket [%d:%d:%d].(%s)\n", si->triplet.family, si->triplet.type, si->triplet.protocol, strerror(errno)); } static void socket_dump(struct object *obj, bool global) { struct socketinfo *si = &obj->sockinfo; struct msg_objcreatedsocket objmsg; output(2, "socket fd:%d domain:%u (%s) type:0x%u protocol:%u\n", si->fd, si->triplet.family, get_domain_name(si->triplet.family), si->triplet.type, si->triplet.protocol); init_msgobjhdr(&objmsg.hdr, OBJ_CREATED_SOCKET, global, obj); objmsg.si.fd = si->fd; objmsg.si.triplet.family = si->triplet.family; objmsg.si.triplet.type = si->triplet.type; objmsg.si.triplet.protocol = si->triplet.protocol; sendudp((char *) &objmsg, sizeof(objmsg)); } static int open_sockets(void) { struct objhead *head; int bytesread = -1; int ret; head = get_objhead(OBJ_GLOBAL, OBJ_FD_SOCKET); head->destroy = &socket_destructor; head->dump = &socket_dump; cachefile = open(cachefilename, O_RDONLY); if (cachefile < 0) { output(1, "Couldn't find socket cachefile. Regenerating.\n"); ret = generate_sockets(); output(1, "created %d sockets\n", nr_sockets); return ret; } lock_cachefile(F_RDLCK); while (bytesread != 0) { unsigned int domain, type, protocol; unsigned int buffer[3]; int fd; bytesread = read(cachefile, buffer, sizeof(int) * 3); if (bytesread == 0) { if (nr_sockets == 0) goto regenerate; break; } domain = buffer[0]; type = buffer[1]; protocol = buffer[2]; if (domain >= TRINITY_PF_MAX) { output(1, "cachefile contained invalid domain %u\n", domain); goto regenerate; } if ((do_specific_domain == TRUE && domain != specific_domain) || (no_domains[domain] == TRUE)) { output(1, "ignoring socket cachefile due to specific " "protocol request (or protocol disabled), " "and stale data in cachefile.\n"); regenerate: unlock_cachefile(); /* drop the reader lock. */ close(cachefile); unlink(cachefilename); ret = generate_sockets(); return ret; } fd = open_socket(domain, type, protocol); if (fd < 0) { output(1, "Cachefile is stale. Need to regenerate.\n"); goto regenerate; } /* check for ctrl-c */ if (shm->exit_reason != STILL_RUNNING) { close(cachefile); return FALSE; } } output(1, "%d sockets created based on info from socket cachefile.\n", nr_sockets); unlock_cachefile(); close(cachefile); return TRUE; } struct socketinfo * get_rand_socketinfo(void) { struct object *obj; /* When using victim files, sockets can be 0. */ if (objects_empty(OBJ_FD_SOCKET) == TRUE) return NULL; obj = get_random_object(OBJ_FD_SOCKET, OBJ_GLOBAL); return &obj->sockinfo; } static int get_rand_socket_fd(void) { struct socketinfo *sockinfo; sockinfo = get_rand_socketinfo(); if (sockinfo == NULL) return -1; return sockinfo->fd; } int fd_from_socketinfo(struct socketinfo *si) { if (si != NULL) { if (!(ONE_IN(1000))) return si->fd; } return get_random_fd(); } static const struct fd_provider socket_fd_provider = { .name = "sockets", .enabled = TRUE, .open = &open_sockets, .get = &get_rand_socket_fd, }; REG_FD_PROV(socket_fd_provider);