Hello community, here is the log from the commit of package trinity for openSUSE:Factory checked in at 2017-05-20 10:13:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/trinity (Old) and /work/SRC/openSUSE:Factory/.trinity.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "trinity" Sat May 20 10:13:37 2017 rev:39 rq:495855 version:1.7+git.20170512 Changes: -------- --- /work/SRC/openSUSE:Factory/trinity/trinity.changes 2017-05-16 14:42:54.082130303 +0200 +++ /work/SRC/openSUSE:Factory/.trinity.new/trinity.changes 2017-05-20 10:13:42.715470746 +0200 @@ -1,0 +2,34 @@ +Thu May 18 11:59:33 UTC 2017 - vsis...@suse.com + +- Update to version 1.7+git.20170512: + * create a thread per child queue + * change decoders to return strings + * mutex needs to protect list walks, not just removal. + * add a server/ copy of zmalloc + * support user CFLAGS in Makefiles + * fix potential use-before-init + * move some udp related server functions to their own file + * output decoded packets to logfiles. + * remove the 'stash' copy of the syscall rec + * print where handshakes came from + * tweak socket buffer sizes. + * timestamp syscall operations. + * timestamp all child messages + * only print setsockopt success if it actually succeeded + * server side packet ordering. + * reset the expected sequence number when a child is respawned + * after iterating the child list once, sleep. + * no implied ordering between packets on spawn/exit/signal + * detect pid changes in child messages + * scope reduction + * misc cleanup + * more cppcheck cleanups + * dump errno if write() to logfile fails + * maintain a packets pending count + * copy incoming packet timestamp into the packet header + * log the last operation number a child did when we get a signal + * use pthread_yield rather than sleep + * send the SIGALARM message from the child that just received it. + * bump the expected sequence nr if we got a SIGALARM + +------------------------------------------------------------------- Old: ---- trinity-1.7+git.20170506.tar.xz New: ---- trinity-1.7+git.20170512.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ trinity.spec ++++++ --- /var/tmp/diff_new_pack.oAEAvk/_old 2017-05-20 10:13:43.303387679 +0200 +++ /var/tmp/diff_new_pack.oAEAvk/_new 2017-05-20 10:13:43.307387114 +0200 @@ -16,9 +16,9 @@ # -%define version_unconverted 1.7+git.20170506 +%define version_unconverted 1.7+git.20170512 Name: trinity -Version: 1.7+git.20170506 +Version: 1.7+git.20170512 Release: 0 Summary: A Linux System call fuzz tester License: GPL-2.0 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.oAEAvk/_old 2017-05-20 10:13:43.351380898 +0200 +++ /var/tmp/diff_new_pack.oAEAvk/_new 2017-05-20 10:13:43.351380898 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/kernelslacker/trinity</param> - <param name="changesrevision">f3764ffc7f46a7aae442a6d9cfb216a72db2d73f</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">a81fba1701ad9250f91f87c7748940525eaaffa4</param></service></servicedata> \ No newline at end of file ++++++ trinity-1.7+git.20170506.tar.xz -> trinity-1.7+git.20170512.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/Makefile new/trinity-1.7+git.20170512/Makefile --- old/trinity-1.7+git.20170506/Makefile 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/Makefile 2017-05-12 20:11:06.000000000 +0200 @@ -16,7 +16,8 @@ CC := $(CROSS_COMPILE)$(CC) LD := $(CROSS_COMPILE)$(LD) -CFLAGS += -Wall -Wextra -g -O2 -I. -Iinclude/ -include config.h -Wimplicit -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D__linux__ +CFLAGS ?= -g -O2 -D_FORTIFY_SOURCE=2 +CFLAGS += -Wall -Wextra -I. -Iinclude/ -include config.h -Wimplicit -D_GNU_SOURCE -D__linux__ CCSTD := $(shell if $(CC) -std=gnu11 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-std=gnu11"; else echo "-std=gnu99"; fi) CFLAGS += $(CCSTD) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/child.c new/trinity-1.7+git.20170512/child.c --- old/trinity-1.7+git.20170506/child.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/child.c 2017-05-12 20:11:06.000000000 +0200 @@ -238,10 +238,7 @@ if (logging_enabled == FALSE) return; - childmsg.hdr.pid = pid; - childmsg.hdr.type = CHILD_SPAWNED; - childmsg.hdr.childno = childno; - + init_msgchildhdr(&childmsg.hdr, CHILD_SPAWNED, pid, childno); sendudp((char *) &childmsg, sizeof(childmsg)); } @@ -438,7 +435,10 @@ if (sigwas != SIGALRM) output(1, "[%d] Back from signal handler! (sig was %s)\n", getpid(), strsignal(sigwas)); - + else { + log_child_signalled(child->num, pids[child->num], SIGALRM, child->op_nr); + child->op_nr++; + } return TRUE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/childops/random-syscall.c new/trinity-1.7+git.20170512/childops/random-syscall.c --- old/trinity-1.7+git.20170506/childops/random-syscall.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/childops/random-syscall.c 2017-05-12 20:11:06.000000000 +0200 @@ -69,29 +69,6 @@ return do32; } -static void fail_sanity(void) -{ - struct childdata *child = this_child(); - - dump_childnos(); - dump_childdata(child); - panic(EXIT_SHM_CORRUPTION); -} - -static void check_sanity(struct syscallrecord *rec, struct syscallrecord *stash) -{ - unsigned int len; - - len = strlen(stash->prebuffer); - if (len != strlen(rec->prebuffer)) { - output(0, "Sanity check failed: prebuffer length changed from %d to %d after syscall:%s(%lx, %lx, %lx).\n", - len, strlen(rec->prebuffer), - print_syscall_name(stash->nr, stash->do32bit), - stash->a1, stash->a2, stash->a3); - fail_sanity(); - } -} - static bool set_syscall_nr(struct syscallrecord *rec) { unsigned int syscallnr; @@ -175,7 +152,7 @@ bool random_syscall(struct childdata *child) { - struct syscallrecord *rec, *stash; + struct syscallrecord *rec; int ret = FALSE; rec = &child->syscall; @@ -190,10 +167,6 @@ output_syscall_prefix(rec); - /* we stash a copy of this stuff in case something stomps the rec struct */ - stash = zmalloc(sizeof(struct syscallrecord)); - memcpy(stash, rec, sizeof(struct syscallrecord)); - /* if (ONE_IN(100)) { if (do_syscall_in_child(rec, child) == FALSE) @@ -202,15 +175,11 @@ */ do_syscall(rec); - check_sanity(rec, stash); - output_syscall_postfix(rec); handle_syscall_ret(rec); ret = TRUE; //fail: - free(stash); - return ret; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/include/child.h new/trinity-1.7+git.20170512/include/child.h --- old/trinity-1.7+git.20170506/include/child.h 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/include/child.h 2017-05-12 20:11:06.000000000 +0200 @@ -57,6 +57,8 @@ void reap_child(struct childdata *child); +void log_child_signalled(int childno, pid_t pid, int sig, unsigned long op_nr); + /* Childops */ bool random_syscall(struct childdata *child); bool read_all_files(struct childdata *child); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/include/syscall.h new/trinity-1.7+git.20170512/include/syscall.h --- old/trinity-1.7+git.20170506/include/syscall.h 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/include/syscall.h 2017-05-12 20:11:06.000000000 +0200 @@ -29,6 +29,9 @@ unsigned long a6; unsigned long retval; + /* timestamp (written before the syscall, and updated afterwards. */ + struct timespec tp; + int errno_post; /* what errno was after the syscall. */ bool do32bit; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/include/udp.h new/trinity-1.7+git.20170512/include/udp.h --- old/trinity-1.7+git.20170506/include/udp.h 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/include/udp.h 2017-05-12 20:11:06.000000000 +0200 @@ -65,6 +65,7 @@ struct trinity_msgchildhdr { enum logmsgtypes type; + struct timespec tp; pid_t pid; int childno; }; @@ -100,6 +101,7 @@ struct msg_childsignalled { struct trinity_msgchildhdr hdr; int sig; + unsigned long op_nr; }; struct msg_objcreatedfile { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/main.c new/trinity-1.7+git.20170512/main.c --- old/trinity-1.7+git.20170506/main.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/main.c 2017-05-12 20:11:06.000000000 +0200 @@ -502,12 +502,13 @@ shm->ready = TRUE; } -static void log_child_signalled(int childno, pid_t pid, int sig) +void log_child_signalled(int childno, pid_t pid, int sig, unsigned long op_nr) { struct msg_childsignalled childmsg; init_msgchildhdr(&childmsg.hdr, CHILD_SIGNALLED, pid, childno); childmsg.sig = sig; + childmsg.op_nr = op_nr; sendudp((char *) &childmsg, sizeof(childmsg)); } @@ -552,7 +553,7 @@ else { debugf("got a signal from child %d (pid %d) (%s)\n", childno, pid, strsignal(WTERMSIG(childstatus))); - log_child_signalled(childno, pid, WTERMSIG(childstatus)); + log_child_signalled(childno, pid, WTERMSIG(childstatus), child->op_nr); } reap_child(shm->children[childno]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/Makefile new/trinity-1.7+git.20170512/server/Makefile --- old/trinity-1.7+git.20170506/server/Makefile 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/server/Makefile 2017-05-12 20:11:06.000000000 +0200 @@ -1,6 +1,7 @@ NR_CPUS := $(shell grep -c ^processor /proc/cpuinfo) -CFLAGS += -Wall -Wextra -g -O2 -I. -I../include/ -Wimplicit -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D__linux__ +CFLAGS ?= -g -O2 -D_FORTIFY_SOURCE=2 +CFLAGS += -Wall -Wextra -I. -I../include/ -Wimplicit -D_GNU_SOURCE -D__linux__ CCSTD := $(shell if $(CC) -std=gnu11 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-std=gnu11"; else echo "-std=gnu99"; fi) CFLAGS += $(CCSTD) @@ -11,7 +12,6 @@ CFLAGS += -Wnested-externs CFLAGS += -Wpacked CFLAGS += -Wshadow -CFLAGS += -Wswitch-enum CFLAGS += -Wundef CFLAGS += -Wwrite-strings CFLAGS += -Wno-format-nonliteral diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/child.c new/trinity-1.7+git.20170512/server/child.c --- old/trinity-1.7+git.20170506/server/child.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/server/child.c 2017-05-12 20:11:06.000000000 +0200 @@ -8,33 +8,58 @@ #include <unistd.h> #include "decode.h" #include "exit.h" +#include "session.h" #include "socketinfo.h" #include "trinity.h" #include "types.h" #include "udp.h" #include "utils.h" -void decode_child_spawned(char *buf) +char * decode_child_spawned(char *buf) { struct msg_childspawned *childmsg; + struct timespec *ts; + struct childdata *child; + void *p = zmalloc(1024); childmsg = (struct msg_childspawned *) buf; - printf("Child spawned. id:%d pid:%d\n", childmsg->hdr.childno, childmsg->hdr.pid); + ts = &childmsg->hdr.tp; + sprintf(p, "%d.%d Child spawned. id:%d pid:%d\n", + (int) ts->tv_sec, (int) ts->tv_nsec, + childmsg->hdr.childno, childmsg->hdr.pid); + + child = &session.children[childmsg->hdr.childno]; + child->childpid = childmsg->hdr.pid; + child->expected_seq = 0; + child->expecting_result = FALSE; + return p; } -void decode_child_exited(char *buf) +char * decode_child_exited(char *buf) { struct msg_childexited *childmsg; + struct timespec *ts; + void *p = zmalloc(1024); childmsg = (struct msg_childexited *) buf; - printf("Child exited. id:%d pid:%d\n", childmsg->hdr.childno, childmsg->hdr.pid); + ts = &childmsg->hdr.tp; + sprintf(p, "%d.%d Child exited. id:%d pid:%d\n", + (int) ts->tv_sec, (int) ts->tv_nsec, + childmsg->hdr.childno, childmsg->hdr.pid); + return p; } -void decode_child_signalled(char *buf) +char * decode_child_signalled(char *buf) { struct msg_childsignalled *childmsg; + struct timespec *ts; + void *p = zmalloc(1024); childmsg = (struct msg_childsignalled *) buf; - printf("Child signal. id:%d pid:%d signal: %s\n", - childmsg->hdr.childno, childmsg->hdr.pid, strsignal(childmsg->sig)); + ts = &childmsg->hdr.tp; + sprintf(p, "%d.%d Child signal. id:%d pid:%d signal: %s. After op:%lu\n", + (int) ts->tv_sec, (int) ts->tv_nsec, + childmsg->hdr.childno, childmsg->hdr.pid, strsignal(childmsg->sig), + childmsg->op_nr); + return p; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/child.h new/trinity-1.7+git.20170512/server/child.h --- old/trinity-1.7+git.20170506/server/child.h 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/child.h 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,13 @@ +#pragma once + +#include "packet.h" + +struct childdata { + pid_t childpid; + struct packet packets; + unsigned int packetcount; + pthread_mutex_t packetmutex; + int logfile; + unsigned long expected_seq; + bool expecting_result; +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/decode.h new/trinity-1.7+git.20170512/server/decode.h --- old/trinity-1.7+git.20170506/server/decode.h 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/server/decode.h 2017-05-12 20:11:06.000000000 +0200 @@ -4,38 +4,38 @@ #include "udp.h" struct msgfunc { - void (*func)(char *buf); + char * (*func)(char *buf); }; extern const struct msgfunc decodefuncs[MAX_LOGMSGTYPE]; -void decode_child_spawned(char *buf); -void decode_child_exited(char *buf); -void decode_child_signalled(char *buf); - -void decode_main_started(char *buf); -void decode_main_exiting(char *buf); -void decode_reseed(char *buf); - -void decode_obj_created_file(char *buf); -void decode_obj_created_map(char *buf); -void decode_obj_created_pipe(char *buf); -void decode_obj_created_perf(char *buf); -void decode_obj_created_epoll(char *buf); -void decode_obj_created_eventfd(char *buf); -void decode_obj_created_timerfd(char *buf); -void decode_obj_created_testfile(char *buf); -void decode_obj_created_memfd(char *buf); -void decode_obj_created_drm(char *buf); -void decode_obj_created_inotify(char *buf); -void decode_obj_created_userfault(char *buf); -void decode_obj_created_fanotify(char *buf); -void decode_obj_created_bpfmap(char *buf); -void decode_obj_created_socket(char *buf); -void decode_obj_created_futex(char *buf); -void decode_obj_created_shm(char *buf); -void decode_obj_destroyed(char *buf); - -void decode_syscalls_enabled(char *buf); -void decode_syscall_prep(char *buf); -void decode_syscall_result(char *buf); +char *decode_child_spawned(char *buf); +char *decode_child_exited(char *buf); +char *decode_child_signalled(char *buf); + +char *decode_main_started(char *buf); +char *decode_main_exiting(char *buf); +char *decode_reseed(char *buf); + +char *decode_obj_created_file(char *buf); +char *decode_obj_created_map(char *buf); +char *decode_obj_created_pipe(char *buf); +char *decode_obj_created_perf(char *buf); +char *decode_obj_created_epoll(char *buf); +char *decode_obj_created_eventfd(char *buf); +char *decode_obj_created_timerfd(char *buf); +char *decode_obj_created_testfile(char *buf); +char *decode_obj_created_memfd(char *buf); +char *decode_obj_created_drm(char *buf); +char *decode_obj_created_inotify(char *buf); +char *decode_obj_created_userfault(char *buf); +char *decode_obj_created_fanotify(char *buf); +char *decode_obj_created_bpfmap(char *buf); +char *decode_obj_created_socket(char *buf); +char *decode_obj_created_futex(char *buf); +char *decode_obj_created_shm(char *buf); +char *decode_obj_destroyed(char *buf); + +char *decode_syscalls_enabled(char *buf); +char *decode_syscall_prep(char *buf); +char *decode_syscall_result(char *buf); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/logfiles.c new/trinity-1.7+git.20170512/server/logfiles.c --- old/trinity-1.7+git.20170506/server/logfiles.c 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/logfiles.c 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,36 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "logfiles.h" +#include "utils.h" + +int open_logfile(const char *logfilename) +{ + int fd; + + fd = open(logfilename, O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (!fd) + printf("## couldn't open logfile %s\n", logfilename); + + return fd; +} + +int open_child_logfile(unsigned int num) +{ + char *logfilename; + int fd; + + logfilename = zmalloc(64); + sprintf(logfilename, "trinity-child%u.log", num); + + fd = open_logfile(logfilename); + if (!fd) + exit(EXIT_FAILURE); + + free(logfilename); + return fd; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/logfiles.h new/trinity-1.7+git.20170512/server/logfiles.h --- old/trinity-1.7+git.20170506/server/logfiles.h 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/logfiles.h 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,4 @@ +#pragma once + +int open_logfile(const char *logfilename); +int open_child_logfile(unsigned int num); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/main.c new/trinity-1.7+git.20170512/server/main.c --- old/trinity-1.7+git.20170506/server/main.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/server/main.c 2017-05-12 20:11:06.000000000 +0200 @@ -13,30 +13,35 @@ #include "udp.h" #include "utils.h" -void decode_main_started(char *buf) +char * decode_main_started(char *buf) { struct msg_mainstarted *mainmsg; + void *p = zmalloc(1024); mainmsg = (struct msg_mainstarted *) buf; - printf("Main started. pid:%d shm:%p-%p initial seed: %u\n", + sprintf(p, "Main started. pid:%d shm:%p-%p initial seed: %u\n", mainmsg->hdr.pid, mainmsg->shm_begin, mainmsg->shm_end, mainmsg->initial_seed); + return p; } -void decode_main_exiting(char *buf) +char * decode_main_exiting(char *buf) { struct msg_mainexiting *mainmsg; + void *p = zmalloc(1024); mainmsg = (struct msg_mainexiting *) buf; - printf("Main exiting. pid:%d Reason: %s\n", mainmsg->hdr.pid, decode_exit(mainmsg->reason)); + sprintf(p, "Main exiting. pid:%d Reason: %s\n", mainmsg->hdr.pid, decode_exit(mainmsg->reason)); + return p; } -void decode_reseed(char *buf) +char * decode_reseed(char *buf) { struct msg_reseed *rsmsg; + void *p = zmalloc(1024); rsmsg = (struct msg_reseed *) buf; - printf("pid %d Reseed. New seed = %d\n", rsmsg->hdr.pid, rsmsg->new_seed); - sleep(5); + sprintf(p, "pid %d Reseed. New seed = %d\n", rsmsg->hdr.pid, rsmsg->new_seed); + return p; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/objects.c new/trinity-1.7+git.20170512/server/objects.c --- old/trinity-1.7+git.20170506/server/objects.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/server/objects.c 2017-05-12 20:11:06.000000000 +0200 @@ -14,29 +14,32 @@ #include "udp.h" #include "utils.h" -void decode_obj_created_file(char *buf) +char * decode_obj_created_file(char *buf) { struct msg_objcreatedfile *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedfile *) buf; if (objmsg->fopened) { - printf("%s file object created at %p by pid %d: fd %d = fopen(\"%s\") ; fcntl(fd, 0x%x)\n", + sprintf(p, "%s file object created at %p by pid %d: fd %d = fopen(\"%s\") ; fcntl(fd, 0x%x)\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->filename, objmsg->fcntl_flags); } else { - printf("%s file object created at %p by pid %d: fd %d = open(\"%s\", 0x%x)\n", + sprintf(p, "%s file object created at %p by pid %d: fd %d = open(\"%s\", 0x%x)\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->filename, objmsg->flags); } + return p; } -void decode_obj_created_map(char *buf) +char * decode_obj_created_map(char *buf) { struct msg_objcreatedmap *objmsg; + void *p = zmalloc(1024); const char *maptypes[] = { "initial anon mmap", "child created anon mmap", @@ -44,155 +47,180 @@ }; objmsg = (struct msg_objcreatedmap *) buf; - printf("%s map object created at %p by pid %d: start:%p size:%ld name:%s prot:%x type:%s\n", + sprintf(p, "%s map object created at %p by pid %d: start:%p size:%ld name:%s prot:%x type:%s\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->start, objmsg->size, objmsg->name, objmsg->prot, maptypes[objmsg->type - 1]); + return p; } -void decode_obj_created_pipe(char *buf) +char * decode_obj_created_pipe(char *buf) { struct msg_objcreatedpipe *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedpipe *) buf; - printf("%s pipe object created at %p by pid %d: fd:%d flags:%x [%s]\n", + sprintf(p, "%s pipe object created at %p by pid %d: fd:%d flags:%x [%s]\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->flags, objmsg->reader ? "reader" : "writer"); + return p; } -void decode_obj_created_perf(char *buf) +char * decode_obj_created_perf(char *buf) { struct msg_objcreatedperf *objmsg; - char *p; + char *str = zmalloc(1024); + char *p = str; + char *ptr; int i; objmsg = (struct msg_objcreatedperf *) buf; - printf("%s perf object created at %p by pid %d: fd:%d pid:%d cpu:%d group_fd:%d flags:%lx eventattr len:%d\n", + p += sprintf(p, "%s perf object created at %p by pid %d: fd:%d pid:%d cpu:%d group_fd:%d flags:%lx eventattr len:%d\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->pid, objmsg->cpu, objmsg->group_fd, objmsg->flags, objmsg->eventattrsize); - printf("perf_event_attr: "); - p = (char *) &objmsg->eventattr; + p += sprintf(p, "perf_event_attr: "); + ptr = (char *) &objmsg->eventattr; for (i = 0; i < objmsg->eventattrsize; i++) { - printf("%02x ", (unsigned char) p[i]); + p += sprintf(p, "%02x ", (unsigned char) ptr[i]); } - printf("\n"); + p += sprintf(p, "\n"); + return str; } -void decode_obj_created_epoll(char *buf) +char * decode_obj_created_epoll(char *buf) { struct msg_objcreatedepoll *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedepoll *) buf; - printf("%s epoll object created at %p by pid %d: fd:%d create1: %s flags:%x\n", + sprintf(p, "%s epoll object created at %p by pid %d: fd:%d create1: %s flags:%x\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->create1 ? "false" : "true", objmsg->flags); + return p; } -void decode_obj_created_eventfd(char *buf) +char * decode_obj_created_eventfd(char *buf) { struct msg_objcreatedeventfd *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedeventfd *) buf; - printf("%s eventfd object created at %p by pid %d: fd:%d count: %d flags:%x\n", + sprintf(p, "%s eventfd object created at %p by pid %d: fd:%d count: %d flags:%x\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->count, objmsg->flags); + return p; } -void decode_obj_created_timerfd(char *buf) +char * decode_obj_created_timerfd(char *buf) { struct msg_objcreatedtimerfd *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedtimerfd *) buf; - printf("%s timerfd object created at %p by pid %d: fd:%d clockid: %d flags:%x\n", + sprintf(p, "%s timerfd object created at %p by pid %d: fd:%d clockid: %d flags:%x\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->clockid, objmsg->flags); + return p; } -void decode_obj_created_testfile(char *buf) +char * decode_obj_created_testfile(char *buf) { struct msg_objcreatedfile *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedfile *) buf; if (objmsg->fopened) { - printf("%s testfile object created at %p by pid %d: fd %d = fopen(\"%s\") ; fcntl(fd, 0x%x)\n", + sprintf(p, "%s testfile object created at %p by pid %d: fd %d = fopen(\"%s\") ; fcntl(fd, 0x%x)\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->filename, objmsg->fcntl_flags); } else { - printf("%s testfile object created at %p by pid %d: fd %d = open(\"%s\", 0x%x)\n", + sprintf(p, "%s testfile object created at %p by pid %d: fd %d = open(\"%s\", 0x%x)\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->filename, objmsg->flags); } + return p; } -void decode_obj_created_memfd(char *buf) +char * decode_obj_created_memfd(char *buf) { struct msg_objcreatedmemfd *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedmemfd *) buf; - printf("%s memfd object created at %p by pid %d: fd:%d name: %s flags:%x\n", + sprintf(p, "%s memfd object created at %p by pid %d: fd:%d name: %s flags:%x\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->name, objmsg->flags); + return p; } -void decode_obj_created_drm(char *buf) +char * decode_obj_created_drm(char *buf) { struct msg_objcreateddrm *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreateddrm *) buf; - printf("%s drm object created at %p by pid %d: fd:%d\n", + sprintf(p, "%s drm object created at %p by pid %d: fd:%d\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd); + return p; } -void decode_obj_created_inotify(char *buf) +char * decode_obj_created_inotify(char *buf) { struct msg_objcreatedinotify *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedinotify *) buf; - printf("%s inotify object created at %p by pid %d: fd:%d flags:%x\n", + sprintf(p, "%s inotify object created at %p by pid %d: fd:%d flags:%x\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->flags); + return p; } -void decode_obj_created_userfault(char *buf) +char * decode_obj_created_userfault(char *buf) { struct msg_objcreateduserfault *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreateduserfault *) buf; - printf("%s userfault object created at %p by pid %d: fd:%d flags:%x\n", + sprintf(p, "%s userfault object created at %p by pid %d: fd:%d flags:%x\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->flags); + return p; } -void decode_obj_created_fanotify(char *buf) +char * decode_obj_created_fanotify(char *buf) { struct msg_objcreatedfanotify *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedfanotify *) buf; - printf("%s fanotify object created at %p by pid %d: fd:%d flags:%x eventflags:%x\n", + sprintf(p, "%s fanotify object created at %p by pid %d: fd:%d flags:%x eventflags:%x\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->fd, objmsg->flags, objmsg->eventflags); + return p; } -void decode_obj_created_bpfmap(char *buf) +char * decode_obj_created_bpfmap(char *buf) { struct msg_objcreatedbpfmap *objmsg; + void *p = zmalloc(1024); const char *bpfmaptypes[] = { "hash", "array", "prog array", "perf_event_array", "percpu hash", "percpu array", "stack trace", "cgroup array", @@ -201,54 +229,63 @@ objmsg = (struct msg_objcreatedbpfmap *) buf; - printf("%s bpf map object created at %p by pid %d: fd:%d type:%s\n", + sprintf(p, "%s bpf map object created at %p by pid %d: fd:%d type:%s\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->map_fd, bpfmaptypes[objmsg->map_type]); + return p; } -void decode_obj_created_socket(char *buf) +char * decode_obj_created_socket(char *buf) { struct msg_objcreatedsocket *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedsocket *) buf; - printf("%s socket object created at %p by pid %d: fd:%d family:%d type:%d protocol:%d\n", + sprintf(p, "%s socket object created at %p by pid %d: fd:%d family:%d type:%d protocol:%d\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->si.fd, objmsg->si.triplet.family, objmsg->si.triplet.type, objmsg->si.triplet.protocol); + return p; } -void decode_obj_created_futex(char *buf) +char * decode_obj_created_futex(char *buf) { struct msg_objcreatedfutex *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedfutex *) buf; - printf("%s futex object created at %p by pid %d: futex:%d owner:%d\n", + sprintf(p, "%s futex object created at %p by pid %d: futex:%d owner:%d\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->futex, objmsg->owner); + return p; } -void decode_obj_created_shm(char *buf) +char * decode_obj_created_shm(char *buf) { struct msg_objcreatedshm *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objcreatedshm *) buf; - printf("%s shm object created at %p by pid %d: id:%u size:%zu flags:%x ptr:%p\n", + sprintf(p, "%s shm object created at %p by pid %d: id:%u size:%zu flags:%x ptr:%p\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->id, objmsg->size, objmsg->flags, objmsg->ptr); + return p; } -void decode_obj_destroyed(char *buf) +char * decode_obj_destroyed(char *buf) { struct msg_objdestroyed *objmsg; + void *p = zmalloc(1024); objmsg = (struct msg_objdestroyed *) buf; - printf("%s object at %p destroyed by pid %d. type:%d\n", + sprintf(p, "%s object at %p destroyed by pid %d. type:%d\n", objmsg->hdr.global ? "global" : "local", objmsg->hdr.address, objmsg->hdr.pid, objmsg->hdr.type); + return p; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/packet.h new/trinity-1.7+git.20170512/server/packet.h --- old/trinity-1.7+git.20170506/server/packet.h 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/packet.h 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,9 @@ +#pragma once + +#include "list.h" + +struct packet { + struct list_head list; + struct timespec tp; + char * data; +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/session.h new/trinity-1.7+git.20170512/server/session.h --- old/trinity-1.7+git.20170506/server/session.h 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/session.h 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,19 @@ +#pragma once + +#include "child.h" + +// TODO: dynamically allocate +#define MAX_CHILDREN 1024 + +struct fuzzsession { + pid_t mainpid; + int num_children; + struct childdata children[MAX_CHILDREN]; + pthread_t childthreads[MAX_CHILDREN]; + + pthread_mutex_t packetmutex; + struct packet mainpackets; + int logfile; +}; + +extern struct fuzzsession session; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/syscalls.c new/trinity-1.7+git.20170512/server/syscalls.c --- old/trinity-1.7+git.20170506/server/syscalls.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/server/syscalls.c 2017-05-12 20:11:06.000000000 +0200 @@ -5,6 +5,7 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> +#include <time.h> #include <unistd.h> #include "decode.h" #include "exit.h" @@ -14,25 +15,28 @@ #include "udp.h" #include "utils.h" -void decode_syscalls_enabled(char *buf) +char * decode_syscalls_enabled(char *buf) { struct msg_syscallsenabled *scmsg; + char *p = zmalloc(1024); + char *str = p; int nr; int i; scmsg = (struct msg_syscallsenabled *) buf; nr = scmsg->nr_enabled; if (scmsg->arch_is_biarch == TRUE) { - printf("Enabled %d %s bit syscalls : { ", nr, scmsg->is_64 ? "64" : "32"); + p += sprintf(p, "Enabled %d %s bit syscalls : { ", nr, scmsg->is_64 ? "64" : "32"); for (i = 0 ; i < nr; i++) - printf("%d ", scmsg->entries[i]); - printf("}\n"); + p += sprintf(p, "%d ", scmsg->entries[i]); + sprintf(p, "}\n"); } else { - printf("Enabled %d syscalls : { ", nr); + p += sprintf(p, "Enabled %d syscalls : { ", nr); for (i = 0 ; i < nr; i++) - printf("%d ", scmsg->entries[i]); - printf("}\n"); + p += sprintf(p, "%d ", scmsg->entries[i]); + sprintf(p, "}\n"); } + return str; } /* @@ -41,28 +45,38 @@ * - if we see another prep from the same child, we must have segv'd. * (maybe handle this in decode_child_signalled ?) */ -void decode_syscall_prep(char *buf) +char * decode_syscall_prep(char *buf) { struct msg_syscallprep *scmsg; + struct timespec *ts; + void *p = zmalloc(1024); scmsg = (struct msg_syscallprep *) buf; + ts = &scmsg->hdr.tp; - printf("Child %d [%d] syscall prep [op:%ld] %d%s (0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", + sprintf(p, "%d.%d Child %d [%d] syscall prep [op:%ld] %d%s (0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", + (int) ts->tv_sec, (int) ts->tv_nsec, scmsg->hdr.childno, scmsg->hdr.pid, scmsg->sequence_nr, scmsg->nr, scmsg->is32bit ? "[32bit]" : "", scmsg->a1, scmsg->a2, scmsg->a3, scmsg->a4, scmsg->a5, scmsg->a6); + return p; } -void decode_syscall_result(char *buf) +char * decode_syscall_result(char *buf) { struct msg_syscallresult *scmsg; + struct timespec *ts; + void *p = zmalloc(1024); scmsg = (struct msg_syscallresult *) buf; + ts = &scmsg->hdr.tp; - printf("Child %d [%d] syscall [op:%ld] result %lx %s\n", + sprintf(p, "%d.%d Child %d [%d] syscall [op:%ld] result %lx %s\n", + (int) ts->tv_sec, (int) ts->tv_nsec, scmsg->hdr.childno, scmsg->hdr.pid, scmsg->sequence_nr, scmsg->retval, scmsg->retval == -1 ? strerror(scmsg->errno_post) : "" ); + return p; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/trinityserver.c new/trinity-1.7+git.20170512/server/trinityserver.c --- old/trinity-1.7+git.20170506/server/trinityserver.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/server/trinityserver.c 2017-05-12 20:11:06.000000000 +0200 @@ -8,109 +8,166 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "child.h" #include "decode.h" #include "exit.h" #include "handshake.h" #include "list.h" +#include "logfiles.h" +#include "packet.h" +#include "session.h" #include "trinity.h" #include "types.h" #include "udp.h" +#include "udp-server.h" #include "utils.h" -struct packet { - struct list_head list; - char * data; -}; - -struct childdata { - pid_t childpid; - struct packet packets; - pthread_mutex_t packetmutex; -}; - -// TODO: dynamically allocate -#define MAX_CHILDREN 1024 -struct fuzzsession { - pid_t mainpid; - int num_children; - struct childdata children[MAX_CHILDREN]; - pthread_mutex_t packetmutex; - struct packet mainpackets; -}; +struct fuzzsession session; -static struct fuzzsession session; - - -static void decode(struct packet *pkt, pthread_mutex_t *packetmutex) +static enum logmsgtypes get_packet_type(struct packet *pkt) { char *buffer = pkt->data; - enum logmsgtypes type = buffer[0]; + return buffer[0]; +} + +static char * decode(struct packet *pkt) +{ + char *str; + enum logmsgtypes type = get_packet_type(pkt); + + str = decodefuncs[type].func((char *) pkt->data); - decodefuncs[type].func((char *) pkt->data); - pthread_mutex_lock(packetmutex); list_del(&pkt->list); - pthread_mutex_unlock(packetmutex); free(pkt->data); free(pkt); + return str; } -static void decoder_func(struct fuzzsession *fs) +static void decode_this_packet(struct childdata *child, struct packet *pkt) { - struct list_head *node, *tmp; - int i; + char *str = decode(pkt); + int ret; - // iterate through queue for main - if (!list_empty(&fs->mainpackets.list)) { - list_for_each_safe(node, tmp, &fs->mainpackets.list) { - if (node != NULL) - decode((struct packet *)node, &fs->packetmutex); - } - } + ret = write(child->logfile, str, strlen(str)); + if (ret == -1) + printf("error writing to child logfile: %s\n", strerror(errno)); + free(str); - // iterate through child queues - for (i = 0; i < fs->num_children; i++) { - if (!list_empty(&fs->children[i].packets.list)) { - list_for_each_safe(node, tmp, &fs->children[i].packets.list) { - if (node != NULL) - decode((struct packet *)node, &fs->children[i].packetmutex); - } - } - } + child->packetcount--; } +static void * decoder_child_func(void *data) +{ + struct childdata *child = (struct childdata *) data; + struct list_head *node = NULL, *tmp; -// TODO: ipv6 - -struct sockaddr_in udpclient; + while (1) { + pthread_mutex_lock(&child->packetmutex); + if (list_empty(&child->packets.list)) + goto done; + + list_for_each_safe(node, tmp, &child->packets.list) { + struct packet *currpkt; + struct trinity_msgchildhdr *childhdr; + enum logmsgtypes type; + + currpkt = (struct packet *) node; + type = get_packet_type(currpkt); + + // The non syscall related messages have no ordering on each other asides from timestamp + switch (type) { + case CHILD_SPAWNED: + case CHILD_EXITED: + // TODO: put lastop in the exit msg and wait until that op before processing this. + // TODO: check signalled->op_nr == expected-1 + decode_this_packet(child, currpkt); + child->expecting_result = FALSE; + continue; + + case CHILD_SIGNALLED: + // TODO: check signalled->op_nr == expected-1 + decode_this_packet(child, currpkt); + child->expecting_result = FALSE; + // TODO: only if SIGALRM + child->expected_seq++; + continue; + default: + break; + } -int socketfd; + /* From here on, type can only be SYSCALL_PREP or SYSCALL_RESULT */ -#define MAXBUF 10240 -static char buf[MAXBUF]; + /* if the pid changed, before we gto a CHILD_SPAWNED, skip */ + childhdr = (struct trinity_msgchildhdr *) currpkt->data; + if (child->childpid != childhdr->pid) + continue; + + if (type == SYSCALL_PREP) { + struct msg_syscallprep *scmsg; + if (child->expecting_result == TRUE) + continue; + + scmsg = (struct msg_syscallprep *) currpkt->data; + if (scmsg->sequence_nr != child->expected_seq) + continue; + + decode_this_packet(child, currpkt); + child->expecting_result = TRUE; + continue; + } -void sendudp(char *buffer, size_t len) -{ - int ret; + if (type == SYSCALL_RESULT) { + struct msg_syscallresult *srmsg; + if (child->expecting_result == FALSE) + continue; + + srmsg = (struct msg_syscallresult *) currpkt->data; + if (srmsg->sequence_nr != child->expected_seq) + continue; + + decode_this_packet(child, currpkt); + child->expecting_result = FALSE; + child->expected_seq++; + continue; + } + } +done: + pthread_mutex_unlock(&child->packetmutex); - ret = sendto(socketfd, buffer, len, 0, (struct sockaddr *) &udpclient, sizeof(udpclient)); - if (ret == -1) { - fprintf(stderr, "sendto: %s\n", strerror(errno)); + pthread_yield(); } + //TODO: if main session exits, we should exit this thread. + return NULL; } -static size_t readudp(void) +static void * decoder_main_func(void *data) { - int ret; - socklen_t addrlen = 0; - - memset(buf, 0, MAXBUF); - - addrlen = sizeof(udpclient); - ret = recvfrom(socketfd, buf, MAXBUF, 0, (struct sockaddr *) &udpclient, &addrlen); - if (ret == -1) - fprintf(stderr, "recvfrom: %s\n", strerror(errno)); + struct fuzzsession *fs = (struct fuzzsession *) data; + struct list_head *node, *tmp; - return ret; + while (1) { + // iterate through queue for main + pthread_mutex_lock(&fs->packetmutex); + if (!list_empty(&fs->mainpackets.list)) { + list_for_each_safe(node, tmp, &fs->mainpackets.list) { + if (node != NULL) { + char *str; + int ret; + str = decode((struct packet *)node); + ret = write(fs->logfile, str, strlen(str)); + if (ret == -1) + printf("error writing to main logfile: %s\n", strerror(errno)); + free(str); + } + } + } + pthread_mutex_unlock(&fs->packetmutex); + //TODO: if main session exits, we should exit this thread. + } + return NULL; } /* simple 2-way handshake just to agree on protocol. */ @@ -130,16 +187,30 @@ session.mainpid = hs->mainpid; session.num_children = hs->num_children; + //TODO: mkdir("logs/") ; chdir ("logs/") + //TODO mkdir session-mainpid + session.logfile = open_logfile("trinity-main.log"); - sendudp(serverreply, strlen(serverreply)); INIT_LIST_HEAD(&session.mainpackets.list); pthread_mutex_init(&session.packetmutex, NULL); for (i = 0; i < hs->num_children; i++) { - INIT_LIST_HEAD(&session.children[i].packets.list); - pthread_mutex_init(&session.children[i].packetmutex, NULL); + struct childdata *child = &session.children[i]; + int ret; + + child->logfile = open_child_logfile(i); + child->expected_seq = 0; + child->expecting_result = FALSE; + INIT_LIST_HEAD(&child->packets.list); + child->packetcount = 0; + pthread_mutex_init(&child->packetmutex, NULL); + ret = pthread_create(&session.childthreads[i], NULL, decoder_child_func, child); + assert(!ret); } + printf("Received handshake from %s:%d\n", inet_ntoa(udpclient.sin_addr), ntohs(udpclient.sin_port)); + sendudp(serverreply, strlen(serverreply)); + return TRUE; } @@ -164,28 +235,6 @@ return __handshake(); } -static bool setup_socket(void) -{ - struct sockaddr_in udpserver; - - socketfd = socket(AF_INET, SOCK_DGRAM, 0); - if (socketfd == -1) { - fprintf(stderr, "Could not create a socket\n"); - return FALSE; - } - - udpserver.sin_family = AF_INET; - udpserver.sin_addr.s_addr = htonl(INADDR_ANY); - udpserver.sin_port = htons(TRINITY_LOG_PORT); - - if (bind(socketfd, (struct sockaddr *) &udpserver, sizeof(udpserver)) != 0) { - fprintf(stderr, "Could not bind to address!\n"); - close(socketfd); - return FALSE; - } - return TRUE; -} - static void add_to_main_queue(void *data, int len) { struct packet *pkt = malloc(sizeof(struct packet)); @@ -210,6 +259,8 @@ // TODO: might be easier if we have mainpid in pkt to find session. struct fuzzsession *fs = &session; struct trinity_msgchildhdr *childhdr; + struct childdata *child; + struct list_head *node, *tmp; pkt->data = malloc(len); if (pkt->data == NULL) { @@ -221,9 +272,33 @@ // We know this is a child packet, so we can assume a trinity_msgchildhdr // FIXME: Not true for objects! childhdr = (struct trinity_msgchildhdr *) pkt->data; - pthread_mutex_lock(&fs->children[childhdr->childno].packetmutex); - list_add_tail(&pkt->list, &fs->children[childhdr->childno].packets.list); - pthread_mutex_unlock(&fs->children[childhdr->childno].packetmutex); + child = &fs->children[childhdr->childno]; + + pkt->tp = childhdr->tp; + + pthread_mutex_lock(&child->packetmutex); + + if (list_empty(&child->packets.list)) + goto tail_add; + + list_for_each_safe(node, tmp, &child->packets.list) { + struct packet *listpkt = (struct packet *) node; + + if (childhdr->tp.tv_sec > listpkt->tp.tv_sec) + continue; + if (childhdr->tp.tv_nsec > listpkt->tp.tv_nsec) + continue; + + list_add(&pkt->list, node); + goto done; + } + +tail_add: + + list_add_tail(&pkt->list, &child->packets.list); +done: + child->packetcount++; + pthread_mutex_unlock(&child->packetmutex); } static void queue_object_msg(struct trinity_msgobjhdr *obj, int len) @@ -290,7 +365,8 @@ int main(__unused__ int argc, __unused__ char* argv[]) { - pthread_t udpthread; + pthread_t udpthread, decode_main_thr; + struct fuzzsession *fs = &session; // TODO; find session from packets int ret; if (setup_socket() == FALSE) @@ -302,10 +378,14 @@ assert(!ret); while (1) { - struct fuzzsession *fs = &session; // TODO; find session from packets - decoder_func(fs); + ret = pthread_create(&decode_main_thr, NULL, decoder_main_func, fs); + assert(!ret); + pthread_join(decode_main_thr, NULL); } + + pthread_exit(NULL); + close(socketfd); out: exit(EXIT_FAILURE); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/udp-server.c new/trinity-1.7+git.20170512/server/udp-server.c --- old/trinity-1.7+git.20170506/server/udp-server.c 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/udp-server.c 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,76 @@ +#include <assert.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +#include <netdb.h> +#include <pthread.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include "udp.h" +#include "udp-server.h" + +// TODO: ipv6 + +struct sockaddr_in udpclient; + +int socketfd; + +#define MAXBUF 10240 +char buf[MAXBUF]; + +void sendudp(char *buffer, size_t len) +{ + int ret; + + ret = sendto(socketfd, buffer, len, 0, (struct sockaddr *) &udpclient, sizeof(udpclient)); + if (ret == -1) { + fprintf(stderr, "sendto: %s\n", strerror(errno)); + } +} + +size_t readudp(void) +{ + int ret; + socklen_t addrlen = 0; + + memset(buf, 0, MAXBUF); + + addrlen = sizeof(udpclient); + ret = recvfrom(socketfd, buf, MAXBUF, 0, (struct sockaddr *) &udpclient, &addrlen); + if (ret == -1) + fprintf(stderr, "recvfrom: %s\n", strerror(errno)); + + return ret; +} + +bool setup_socket(void) +{ + struct sockaddr_in udpserver; + int rcvbuf; + int ret; + + socketfd = socket(AF_INET, SOCK_DGRAM, 0); + if (socketfd == -1) { + fprintf(stderr, "Could not create a socket\n"); + return FALSE; + } + + udpserver.sin_family = AF_INET; + udpserver.sin_addr.s_addr = htonl(INADDR_ANY); + udpserver.sin_port = htons(TRINITY_LOG_PORT); + + if (bind(socketfd, (struct sockaddr *) &udpserver, sizeof(udpserver)) != 0) { + fprintf(stderr, "Could not bind to address!\n"); + close(socketfd); + return FALSE; + } + + rcvbuf = 1000000 * 64; //TODO: adjust 64 to max_children + ret = setsockopt(socketfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); + if (ret == 0) + printf("Recieve socket buffer size set to %d\n", rcvbuf); + + return TRUE; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/udp-server.h new/trinity-1.7+git.20170512/server/udp-server.h --- old/trinity-1.7+git.20170506/server/udp-server.h 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/udp-server.h 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,12 @@ +#pragma once + +extern struct sockaddr_in udpclient; + +extern int socketfd; + +#define MAXBUF 10240 +extern char buf[MAXBUF]; + +void sendudp(char *buffer, size_t len); +size_t readudp(void); +bool setup_socket(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/server/utils.c new/trinity-1.7+git.20170512/server/utils.c --- old/trinity-1.7+git.20170506/server/utils.c 1970-01-01 01:00:00.000000000 +0100 +++ new/trinity-1.7+git.20170512/server/utils.c 2017-05-12 20:11:06.000000000 +0200 @@ -0,0 +1,31 @@ +//TODO: eventually this file will go away, and we'll just share parts of +// the top-level utils.c + +#include <errno.h> +#include <sys/mman.h> +#include <signal.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "utils.h" + +void * __zmalloc(size_t size, const char *func) +{ + void *p; + + p = malloc(size); + if (p == NULL) { + /* Maybe we mlockall'd everything. Try and undo that, and retry. */ + munlockall(); + p = malloc(size); + if (p != NULL) + goto done; + + printf("%s: malloc(%zu) failure.\n", func, size); + exit(EXIT_FAILURE); + } + +done: + memset(p, 0, size); + return p; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/syscall.c new/trinity-1.7+git.20170512/syscall.c --- old/trinity-1.7+git.20170506/syscall.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/syscall.c 2017-05-12 20:11:06.000000000 +0200 @@ -195,6 +195,7 @@ scmsg.a4 = rec->a4; scmsg.a5 = rec->a5; scmsg.a6 = rec->a6; + rec->tp = scmsg.hdr.tp; sendudp((char *) &scmsg, sizeof(scmsg)); call = rec->nr; @@ -205,6 +206,9 @@ else /* common-case, do the syscall in this child process. */ __do_syscall(rec, BEFORE); + + /* timestamp again for when we returned */ + clock_gettime(CLOCK_MONOTONIC, &rec->tp); } /* @@ -250,6 +254,7 @@ unsigned int call; init_msgchildhdr(&scmsg.hdr, SYSCALL_RESULT, pids[child->num], child->num); + scmsg.hdr.tp = rec->tp; scmsg.sequence_nr = child->op_nr; scmsg.retval = rec->retval; scmsg.errno_post = rec->errno_post; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/tools/Makefile new/trinity-1.7+git.20170512/tools/Makefile --- old/trinity-1.7+git.20170506/tools/Makefile 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/tools/Makefile 2017-05-12 20:11:06.000000000 +0200 @@ -4,7 +4,8 @@ CC := $(CROSS_COMPILE)$(CC) LD := $(CROSS_COMPILE)$(LD) -CFLAGS += -Wall -W -g -O2 -I. -Iinclude/ -Wimplicit -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D__linux__ +CFLAGS ?= -g -O2 -D_FORTIFY_SOURCE=2 +CFLAGS += -Wall -W -I. -Iinclude/ -Wimplicit -D_GNU_SOURCE -D__linux__ ifneq ($(SYSROOT),) CFLAGS += --sysroot=$(SYSROOT) endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trinity-1.7+git.20170506/udp.c new/trinity-1.7+git.20170512/udp.c --- old/trinity-1.7+git.20170506/udp.c 2017-05-06 06:52:58.000000000 +0200 +++ new/trinity-1.7+git.20170512/udp.c 2017-05-12 20:11:06.000000000 +0200 @@ -29,6 +29,8 @@ void init_msgchildhdr(struct trinity_msgchildhdr *hdr, enum logmsgtypes type, pid_t pid, int childno) { + clock_gettime(CLOCK_MONOTONIC, &hdr->tp); + hdr->type = type; hdr->pid = pid; hdr->childno = childno; @@ -132,9 +134,10 @@ struct hostent *he; struct sockaddr_in udpclient; struct in_addr **addr_list; - char *ip; + char *ip = NULL; int ret; unsigned int i; + int sendbuff; if (optarg == NULL) { logging_enabled = FALSE; @@ -154,6 +157,10 @@ udpserver.sin_addr.s_addr = inet_addr(ip); udpserver.sin_port = htons(TRINITY_LOG_PORT); } + + if (ip == NULL) + return; + printf("Logging to %s\n", ip); logsocket = socket(AF_INET, SOCK_DGRAM, 0); @@ -173,6 +180,10 @@ exit(EXIT_FAILURE); } + sendbuff = 1000000 * max_children; + ret = setsockopt(logsocket, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)); + printf("socket buffer size set to: %d. (res:%s)\n", sendbuff, strerror(errno)); + /* We temporarily turn enabled on, as we need it for sendudp to work. * If we don't get a valid handshake we turn it back off. */