Hello everyone,

This isn't small patch but most of it was to remove silly loop in the 
child_random_syscalls function. The way I did it is by introducing an 
array of activated syscalls, which contains an index of the syscall in the 
syscalltable(32/64). This way we do not loop, just select one that is 
active and proceed.

Also, improved toggle_syscall functions (for biarch and not) by removing 
search by name as much as possible, thus, no need for loopup_name function 
anymore.

Furthermore, instead of commented out section of code (abbriviated with 
FIXME) that never selected 32 bit version of syscall if a 64 bit version 
existed I added a parameter to control this selection (more in README 
file). By default the chances will be 50/50, but one can control it.

Finally, cleaned up some areas (e.g., got rid of COLOR_ARG macro, by 
converting it to a function) and fixed one bug with wrong variable being 
used.

Signed-off-by: Ildar Muslukhov <[email protected]>

---
 README                     |   2 +
 children/random-syscalls.c |  42 ++---
 include/constants.h        |   2 +
 include/log.h              |   3 +
 include/params.h           |   1 +
 include/shm.h              |   8 +
 include/syscall.h          |   3 +-
 params.c                   |  11 +-
 syscall.c                  | 155 ++++++++--------
 tables.c                   | 442 ++++++++++++++++++++++++---------------------
 trinity.c                  |  12 +-
 11 files changed, 375 insertions(+), 307 deletions(-)

diff --git a/README b/README
index f09d4b5..02fa767 100644
--- a/README
+++ b/README
@@ -105,6 +105,8 @@ tmp directory. (Handy for cleaning up any garbage named 
files; just rm -rf tmp a
  --ioctls/-I will dump all available ioctls.
 
  --arch/-a Explicit selection of 32 or 64 bit variant of system calls.
+
+ --prob32, -b: sets the probability of 32 bit calls being selected (default 
50%)
 
 #######################################################################
 
diff --git a/children/random-syscalls.c b/children/random-syscalls.c
index 767a50a..0cc3d83 100644
--- a/children/random-syscalls.c
+++ b/children/random-syscalls.c
@@ -6,6 +6,7 @@
 #include <unistd.h>
 
 #include "trinity.h"   // biarch
+#include "params.h"
 #include "child.h"
 #include "syscall.h"
 #include "log.h"
@@ -20,9 +21,15 @@
  * to 'we asked to do a 32bit only syscall' and more.. Hairy.
  */
 
+int *active_syscalls = NULL;
+unsigned int nr_active_syscalls = 0;
+
 static void choose_syscall_table(int childno)
 {
-       if (biarch == TRUE) {
+       if (biarch == FALSE) {
+               active_syscalls = shm->active_syscalls;
+               nr_active_syscalls = shm->nr_active_syscalls;
+       } else if (biarch == TRUE) {
 
                /* First, check that we have syscalls enabled in either table. 
*/
                if (validate_syscall_table_64() == FALSE) {
@@ -41,17 +48,19 @@ static void choose_syscall_table(int childno)
                         */
                        shm->do32bit[childno] = FALSE;
 
-// FIXME: I forgot why this got disabled. Revisit.
-//                     if (rand() % 100 < 10)
-//                             shm->do32bit[childno] = TRUE;
+                       if (rand() % 100 < probability_32bit)
+                               shm->do32bit[childno] = TRUE;
                }
 
-
                if (shm->do32bit[childno] == FALSE) {
                        syscalls = syscalls_64bit;
+                       nr_active_syscalls = shm->nr_active_64bit_syscalls;
+                       active_syscalls = shm->active_syscalls64;
                        max_nr_syscalls = max_nr_64bit_syscalls;
                } else {
                        syscalls = syscalls_32bit;
+                       nr_active_syscalls = shm->nr_active_32bit_syscalls;
+                       active_syscalls = shm->active_syscalls32;
                        max_nr_syscalls = max_nr_32bit_syscalls;
                }
        }
@@ -85,28 +94,19 @@ int child_random_syscalls(int childno)
 
                choose_syscall_table(childno);
 
-               //FIXME: This 'loop' here is pretty gross. If we're just fuzzing
-               // a few syscalls, we can spin here for quite a while.
-               // a better way would be to do something in tables.c where we 
construct
-               // our own syscall table just containing enabled syscalls.
-retry:
-               if (no_syscalls_enabled() == TRUE) {
+               if (nr_active_syscalls == 0) {
+                       printf("OOPS: no syscalls enabled\n");
                        shm->exit_reason = EXIT_NO_SYSCALLS_ENABLED;
                        goto out;
                }
 
-               if (shm->exit_reason != STILL_RUNNING)
+               if (shm->exit_reason != STILL_RUNNING) {
+                       printf("Main is not running, exiting");
                        goto out;
+               }
 
-               syscallnr = rand() % max_nr_syscalls;
-
-               if (!(syscalls[syscallnr].entry->flags & ACTIVE))
-                       goto retry;
-
-               if (validate_specific_syscall_silent(syscalls, syscallnr) == 
FALSE)
-                       goto retry;
-
-               /* if we get here, syscallnr is finally valid */
+               syscallnr = rand() % nr_active_syscalls;
+               syscallnr = active_syscalls[syscallnr] - 1;
 
                shm->syscallno[childno] = syscallnr;
 
diff --git a/include/constants.h b/include/constants.h
index 9ee7378..a57fd60 100644
--- a/include/constants.h
+++ b/include/constants.h
@@ -12,4 +12,6 @@
 
 #define REGENERATION_POINT 100000
 
+#define MAX_NR_SYSCALL 1024
+
 #endif /* _CONSTANTS_H */
diff --git a/include/log.h b/include/log.h
index f3fc7c4..627985c 100644
--- a/include/log.h
+++ b/include/log.h
@@ -19,6 +19,9 @@
 #define WHITE if (monochrome == FALSE) sptr += sprintf(sptr, "%s", ANSI_WHITE);
 #define CRESET if (monochrome == FALSE)        sptr += sprintf(sptr, "%s", 
ANSI_RESET);
 
+#define CYANPTR if (monochrome == FALSE)       *sptr += sprintf(*sptr, "%s", 
ANSI_CYAN);
+#define CRESETPTR if (monochrome == FALSE)     *sptr += sprintf(*sptr, "%s", 
ANSI_RESET);
+
 #define MAX_LOGLEVEL 3
 unsigned int highest_logfile(void);
 void synclogs(void);
diff --git a/include/params.h b/include/params.h
index ceec651..747e825 100644
--- a/include/params.h
+++ b/include/params.h
@@ -31,6 +31,7 @@ extern char *victim_path;
 extern bool no_files;
 extern bool random_selection;
 extern unsigned int random_selection_num;
+extern int probability_32bit;
 
 extern int kernel_taint_initial;
 extern int kernel_taint_mask;
diff --git a/include/shm.h b/include/shm.h
index 7aed52c..4495d91 100644
--- a/include/shm.h
+++ b/include/shm.h
@@ -21,6 +21,14 @@ struct shm_s {
        unsigned int seed;
        unsigned int seeds[MAX_NR_CHILDREN];
        unsigned int reseed_counter;
+
+       //Indices of syscall in syscall table that are active. All indices 
shifted by +1. Empty index equals to 0.
+       int active_syscalls32[MAX_NR_SYSCALL];
+       int active_syscalls64[MAX_NR_SYSCALL];
+       int active_syscalls[MAX_NR_SYSCALL];
+       unsigned int nr_active_syscalls;
+       unsigned int nr_active_32bit_syscalls;
+       unsigned int nr_active_64bit_syscalls;
 
        pid_t pids[MAX_NR_CHILDREN];
        unsigned char child_type[MAX_NR_CHILDREN];
diff --git a/include/syscall.h b/include/syscall.h
index faaeafc..d4b5747 100644
--- a/include/syscall.h
+++ b/include/syscall.h
@@ -35,6 +35,7 @@ struct syscall {
        int (*init)(void);
 
        unsigned int number;
+       unsigned int active_number;
        const char name[80];
        const unsigned int num_args;
        unsigned int flags;
@@ -118,7 +119,7 @@ extern bool use_64bit;
 void select_syscall_tables(void);
 int search_syscall_table(const struct syscalltable *table, unsigned int 
nr_syscalls, const char *arg);
 void mark_all_syscalls_active(void);
-void toggle_syscall(const char *arg, unsigned char state);
+void toggle_syscall(const char *arg, bool state);
 void dump_syscall_tables(void);
 int setup_syscall_group(unsigned int desired_group);
 int validate_syscall_tables(void);
diff --git a/params.c b/params.c
index 63901dd..43c70b6 100644
--- a/params.c
+++ b/params.c
@@ -36,6 +36,7 @@ bool logging = TRUE;
 bool do_syslog = FALSE;
 bool random_selection = FALSE;
 unsigned int random_selection_num;
+int probability_32bit = 50;
 bool no_files = FALSE;
 
 bool user_set_seed = FALSE;
@@ -67,7 +68,8 @@ static void usage(void)
        fprintf(stderr, " --syslog,-S: log important info to syslog. (useful if 
syslog is remote)\n");
        fprintf(stderr, " --verbose,-v: increase output verbosity.\n");
        fprintf(stderr, " --victims,-V: path to victim files.\n");
-       fprintf(stderr, " --arch, -a: selects syscalls for the specified 
architecture (32 or 64). Both by default.");
+       fprintf(stderr, " --arch, -a: selects syscalls for the specified 
architecture (32 or 64). Both by default.\n");
+       fprintf(stderr, " --prob32, -b: sets the probability of 32 bit calls 
being selected (default 50%%).\n");
        fprintf(stderr, "\n");
        fprintf(stderr, " -c#,@: target specific syscall (takes syscall name as 
parameter and @ as architecture. No @ defaults to both archs.).\n");
        fprintf(stderr, " -N#: do # syscalls then exit.\n");
@@ -96,6 +98,7 @@ static const struct option longopts[] = {
        { "victims", required_argument, NULL, 'V' },
        { "verbose", no_argument, NULL, 'v' },
        { "arch", required_argument, NULL, 'a' },
+       { "prob32", required_argument, NULL, 'b'},
        { NULL, 0, NULL, 0 } };
 
 
@@ -103,7 +106,7 @@ void parse_args(int argc, char *argv[])
 {
        int opt;
 
-       while ((opt = getopt_long(argc, argv, 
"a:c:C:dDg:hIl:LN:mnP:pqr:s:t:SV:vx:", longopts, NULL)) != -1) {
+       while ((opt = getopt_long(argc, argv, 
"a:b:c:C:dDg:hIl:LN:mnP:pqr:s:t:SV:vx:", longopts, NULL)) != -1) {
                switch (opt) {
                default:
                        if (opt == '?')
@@ -115,6 +118,10 @@ void parse_args(int argc, char *argv[])
                case '\0':
                        return;
 
+               case 'b':
+                       probability_32bit = strtol(optarg, NULL, 10);
+                       break;
+
                case 'c':
                        /* syscalls are all disabled at this point. enable the 
syscall we care about. */
                        do_specific_syscall = TRUE;
diff --git a/syscall.c b/syscall.c
index 63f25a6..6dad4d1 100644
--- a/syscall.c
+++ b/syscall.c
@@ -131,6 +131,70 @@ static unsigned long do_syscall(int childno, int 
*errno_saved)
        return ret;
 }
 
+static void color_arg(unsigned int call,unsigned int argnum, const char *name, 
unsigned long oldreg, unsigned long reg, int type, char **sptr) {
+
+       if (syscalls[call].entry->num_args >= argnum) {
+               if (!name) return;
+
+               if (argnum != 1) {
+                       CRESETPTR
+                       *sptr += sprintf(*sptr, ", ");
+               }
+               if (name)
+                       *sptr += sprintf(*sptr, "%s=", name);
+
+               if (oldreg == reg) {
+                       CRESETPTR
+               } else {
+                       CYANPTR
+               }
+
+               switch(type) {
+                       case ARG_PATHNAME:
+                               *sptr += sprintf(*sptr, "\"%s\"", (char *) reg);
+                       break;
+                       case ARG_PID:
+                       case ARG_FD:
+                               CRESETPTR
+                               *sptr += sprintf(*sptr, "%ld", reg);
+                       break;
+                       case ARG_MODE_T:
+                               CRESETPTR
+                               *sptr += sprintf(*sptr, "%o", (mode_t) reg);
+                       break;
+                       case ARG_UNDEFINED:
+                       case ARG_LEN:
+                       case ARG_ADDRESS:
+                       case ARG_NON_NULL_ADDRESS:
+                       case ARG_RANGE:
+                       case ARG_OP:
+                       case ARG_LIST:
+                       case ARG_RANDPAGE:
+                       case ARG_CPU:
+                       case ARG_RANDOM_LONG:
+                       case ARG_IOVEC:
+                       case ARG_IOVECLEN:
+                       case ARG_SOCKADDR:
+                       case ARG_SOCKADDRLEN:
+                       default:
+                               if (reg > 8 * 1024)
+                                       *sptr += sprintf(*sptr, "0x%lx", reg);
+                               else
+                                       *sptr += sprintf(*sptr, "%ld", reg);
+                               CRESETPTR
+                       break;
+               }
+               if (reg == (((unsigned long)page_zeros) & PAGE_MASK))
+                       *sptr += sprintf(*sptr, "[page_zeros]");
+               if (reg == (((unsigned long)page_rand) & PAGE_MASK))
+                       *sptr += sprintf(*sptr, "[page_rand]");
+               if (reg == (((unsigned long)page_0xff) & PAGE_MASK))
+                       *sptr += sprintf(*sptr, "[page_0xff]");
+               if (reg == (((unsigned long)page_allocs) & PAGE_MASK))
+                       *sptr += sprintf(*sptr, "[page_allocs]");
+       }
+}
+
 /*
  * Generate arguments, print them out, then call the syscall.
  */
@@ -168,85 +232,24 @@ long mkcall(int childno)
        if (syscalls[call].entry->sanitise)
                syscalls[call].entry->sanitise(childno);
 
-/*
- * I *really* loathe how this macro has grown. It should be a real function 
one day.
- */
-#define COLOR_ARG(ARGNUM, NAME, BIT, OLDREG, REG, TYPE)                        
\
-       if ((logging == FALSE) && (quiet_level < MAX_LOGLEVEL))         \
-               goto args_done;                                         \
-                                                                       \
-       if (syscalls[call].entry->num_args >= ARGNUM) {                 \
-               if (!NAME)                                              \
-                       goto args_done;                                 \
-               if (ARGNUM != 1) {                                      \
-                       CRESET                                          \
-                       sptr += sprintf(sptr, ", ");                    \
-               }                                                       \
-               if (NAME)                                               \
-                       sptr += sprintf(sptr, "%s=", NAME);             \
-                                                                       \
-               if (OLDREG == REG) {                                    \
-                       CRESET                                          \
-               } else {                                                \
-                       CYAN                                            \
-               }                                                       \
-                                                                       \
-               switch(TYPE) {                                          \
-               case ARG_PATHNAME:                                      \
-                       sptr += sprintf(sptr, "\"%s\"", (char *) REG);  \
-                       break;                                          \
-               case ARG_PID:                                           \
-               case ARG_FD:                                            \
-                       CRESET                                          \
-                       sptr += sprintf(sptr, "%ld", REG);              \
-                       break;                                          \
-               case ARG_MODE_T:                                        \
-                       CRESET                                          \
-                       sptr += sprintf(sptr, "%o", (mode_t) REG);      \
-                       break;                                          \
-               case ARG_UNDEFINED:                                     \
-               case ARG_LEN:                                           \
-               case ARG_ADDRESS:                                       \
-               case ARG_NON_NULL_ADDRESS:                              \
-               case ARG_RANGE:                                         \
-               case ARG_OP:                                            \
-               case ARG_LIST:                                          \
-               case ARG_RANDPAGE:                                      \
-               case ARG_CPU:                                           \
-               case ARG_RANDOM_LONG:                                   \
-               case ARG_IOVEC:                                         \
-               case ARG_IOVECLEN:                                      \
-               case ARG_SOCKADDR:                                      \
-               case ARG_SOCKADDRLEN:                                   \
-               default:                                                \
-                       if (REG > 8 * 1024)                             \
-                               sptr += sprintf(sptr, "0x%lx", REG);    \
-                       else                                            \
-                               sptr += sprintf(sptr, "%ld", REG);      \
-                       CRESET                                          \
-                       break;                                          \
-               }                                                       \
-               if (REG == (((unsigned long)page_zeros) & PAGE_MASK))   \
-                       sptr += sprintf(sptr, "[page_zeros]");          \
-               if (REG == (((unsigned long)page_rand) & PAGE_MASK))    \
-                       sptr += sprintf(sptr, "[page_rand]");           \
-               if (REG == (((unsigned long)page_0xff) & PAGE_MASK))    \
-                       sptr += sprintf(sptr, "[page_0xff]");           \
-               if (REG == (((unsigned long)page_allocs) & PAGE_MASK))  \
-                       sptr += sprintf(sptr, "[page_allocs]");         \
+       if ((logging == TRUE) && (quiet_level == MAX_LOGLEVEL)) {
+               CRESET
+               sptr += sprintf(sptr, "(");
+               color_arg(call, 1, syscalls[call].entry->arg1name, olda1, 
shm->a1[childno],
+                               syscalls[call].entry->arg1type, &sptr);
+               color_arg(call, 2, syscalls[call].entry->arg2name, olda2, 
shm->a2[childno],
+                               syscalls[call].entry->arg2type, &sptr);
+               color_arg(call, 3, syscalls[call].entry->arg3name, olda3, 
shm->a3[childno],
+                               syscalls[call].entry->arg3type, &sptr);
+               color_arg(call, 4, syscalls[call].entry->arg4name, olda4, 
shm->a4[childno],
+                               syscalls[call].entry->arg4type, &sptr);
+               color_arg(call, 5, syscalls[call].entry->arg5name, olda5, 
shm->a5[childno],
+                               syscalls[call].entry->arg5type, &sptr);
+               color_arg(call, 6, syscalls[call].entry->arg6name, olda6, 
shm->a6[childno],
+                               syscalls[call].entry->arg6type, &sptr);
        }
 
        CRESET
-       sptr += sprintf(sptr, "(");
-
-       COLOR_ARG(1, syscalls[call].entry->arg1name, 1<<5, olda1, 
shm->a1[childno], syscalls[call].entry->arg1type);
-       COLOR_ARG(2, syscalls[call].entry->arg2name, 1<<4, olda2, 
shm->a2[childno], syscalls[call].entry->arg2type);
-       COLOR_ARG(3, syscalls[call].entry->arg3name, 1<<3, olda3, 
shm->a3[childno], syscalls[call].entry->arg3type);
-       COLOR_ARG(4, syscalls[call].entry->arg4name, 1<<2, olda4, 
shm->a4[childno], syscalls[call].entry->arg4type);
-       COLOR_ARG(5, syscalls[call].entry->arg5name, 1<<1, olda5, 
shm->a5[childno], syscalls[call].entry->arg5type);
-       COLOR_ARG(6, syscalls[call].entry->arg6name, 1<<0, olda6, 
shm->a6[childno], syscalls[call].entry->arg6type);
-args_done:
-       CRESET
        sptr += sprintf(sptr, ") ");
        *sptr = '\0';
 
diff --git a/tables.c b/tables.c
index 306decc..f7d3a5b 100644
--- a/tables.c
+++ b/tables.c
@@ -13,6 +13,7 @@
 #include "syscall.h"
 #include "params.h"
 #include "log.h"
+#include "shm.h"
 
 const struct syscalltable *syscalls;
 const struct syscalltable *syscalls_32bit;
@@ -69,40 +70,83 @@ int validate_specific_syscall_silent(const struct 
syscalltable *table, int call)
        return TRUE;
 }
 
-void count_syscalls_enabled(void)
-{
-       unsigned int i;
-       unsigned int ecount_32 = 0, ecount_64 = 0;
-       unsigned int dcount_32 = 0, dcount_64 = 0;
-
-       if (biarch == TRUE) {
-               for_each_64bit_syscall(i) {
-                       if (syscalls_64bit[i].entry->flags & ACTIVE)
-                               ecount_64++;
-                       else
-                               dcount_64++;
+static void activate_syscall_in_table(unsigned int calln, unsigned int 
*nr_active, const struct syscalltable *table, int *active_syscall) {
+       struct syscall *call_ptr;
+
+       call_ptr = table[calln].entry;
+
+       printf("activating syscal %d, activated number %d", calln, *nr_active);
+       //Check if the call is activated already, and activate it only if needed
+       if (call_ptr->active_number == 0) {
+               //Sanity check
+               if ((*nr_active + 1) > MAX_NR_SYSCALL) {
+                       output(0, "[tables] MAX_NR_SYSCALL needs to be 
increased. More syscalls than active table can fit.\n");
+                       exit(EXIT_FAILURE);
                }
 
-               for_each_32bit_syscall(i) {
-                       if (syscalls_32bit[i].entry->flags & ACTIVE)
-                               ecount_32++;
-                       else
-                               dcount_32++;
+               //save the call no
+               active_syscall[*nr_active] = calln + 1;
+               (*nr_active) += 1;
+               call_ptr->active_number = *nr_active;
+       }
+       printf("...done, activated number %d\n", *nr_active);
+}
+
+static void activate_syscall32(unsigned int calln) {
+       activate_syscall_in_table(calln, &shm->nr_active_32bit_syscalls, 
syscalls_32bit, shm->active_syscalls32);
+}
+
+static void activate_syscall64(unsigned int calln) {
+       activate_syscall_in_table(calln, &shm->nr_active_64bit_syscalls, 
syscalls_64bit, shm->active_syscalls64);
+}
+
+static void activate_syscall(unsigned int calln) {
+       activate_syscall_in_table(calln, &shm->nr_active_syscalls, syscalls, 
shm->active_syscalls);
+}
+
+static void deactivate_syscall_in_table(unsigned int calln, unsigned int 
*nr_active, const struct syscalltable *table, int *active_syscall) {
+       struct syscall *call_ptr;
+
+       call_ptr = table[calln].entry;
+       //Check if the call is activated already, and deactivate it only if 
needed
+       if (call_ptr->active_number != 0) {
+               *nr_active -= 1;
+               if (call_ptr->active_number == *nr_active) {
+                       //simple case, we are in the end
+                       active_syscall[*nr_active] = 0;
+               } else {
+                       //in the middle
+                       active_syscall[call_ptr->active_number - 1] = 
active_syscall[*nr_active];
+                       active_syscall[*nr_active] = 0;
                }
+               call_ptr->active_number = 0;
+       }
+
+}
+
+static void deactivate_syscall32(unsigned int calln) {
+       deactivate_syscall_in_table(calln, &shm->nr_active_32bit_syscalls, 
syscalls_32bit, shm->active_syscalls32);
+}
+
+static void deactivate_syscall64(unsigned int calln) {
+       deactivate_syscall_in_table(calln, &shm->nr_active_64bit_syscalls, 
syscalls_64bit, shm->active_syscalls64);
+}
+
+static void deactivate_syscall(unsigned int calln) {
+       deactivate_syscall_in_table(calln, &shm->nr_active_syscalls, syscalls, 
shm->active_syscalls);
+}
+
+void count_syscalls_enabled(void)
+{
+       if (biarch == TRUE) {
                printf("[%d] 32-bit syscalls: %d enabled, %d disabled.  "
                        "64-bit syscalls: %d enabled, %d disabled.\n",
-                       getpid(), ecount_32, dcount_32, ecount_64, dcount_64);
-
+                       getpid(),
+                       shm->nr_active_32bit_syscalls, max_nr_32bit_syscalls - 
shm->nr_active_32bit_syscalls,
+                       shm->nr_active_64bit_syscalls, max_nr_64bit_syscalls - 
shm->nr_active_64bit_syscalls);
        } else {
-
-               /* non-biarch */
-               for_each_syscall(i) {
-                       if (syscalls[i].entry->flags & ACTIVE)
-                               ecount_32++;
-                       else
-                               dcount_32++;
-               }
-               printf("[%d] Enabled %d syscalls. Disabled %d syscalls.\n", 
getpid(), ecount_32, dcount_32);
+               printf("[%d] Enabled %d syscalls. Disabled %d syscalls.\n",
+                       getpid(), shm->nr_active_syscalls, max_nr_syscalls - 
shm->nr_active_syscalls);
        }
 }
 
@@ -113,7 +157,7 @@ void init_syscalls(void)
        if (biarch == TRUE) {
                for_each_64bit_syscall(i) {
                        if (syscalls_64bit[i].entry->flags & ACTIVE)
-                               if (syscalls_64bit[i].entry->init)
+                               if (syscalls_64bit[i].entry->init)
                                        syscalls_64bit[i].entry->init();
                }
 
@@ -137,58 +181,44 @@ void init_syscalls(void)
 
 bool no_syscalls_enabled(void)
 {
-       unsigned int i;
-
        if (biarch == TRUE) {
-               for_each_64bit_syscall(i) {
-                       if (syscalls_64bit[i].entry->flags & ACTIVE)
-                               return FALSE;
-               }
-               for_each_32bit_syscall(i) {
-                       if (syscalls_32bit[i].entry->flags & ACTIVE)
-                               return FALSE;
-               }
-               return TRUE;
+               if ((shm->nr_active_32bit_syscalls == 0) && 
(shm->nr_active_64bit_syscalls == 0))
+                       return TRUE;
+               else
+                       return FALSE;
        }
 
        /* non-biarch */
-       for_each_syscall(i) {
-               if (syscalls[i].entry->flags & ACTIVE)
-                       return FALSE;
-       }
-       return TRUE;
+       if (shm->nr_active_syscalls == 0)
+               return TRUE;
+       else
+               return FALSE;
 }
 
 int validate_syscall_table_64(void)
 {
-       unsigned int i;
+       if (shm->nr_active_64bit_syscalls == 0)
+               use_64bit = FALSE;
+       else
+               use_64bit = TRUE;
 
-       for_each_64bit_syscall(i) {
-               if (syscalls_64bit[i].entry->flags & ACTIVE) {
-                       use_64bit = TRUE;
-                       break;
-               }
-       }
        return use_64bit;
 }
 
 int validate_syscall_table_32(void)
 {
-       unsigned int i;
+       if (shm->nr_active_32bit_syscalls == 0)
+               use_32bit = FALSE;
+       else
+               use_32bit = TRUE;
 
-       for_each_32bit_syscall(i) {
-               if (syscalls_32bit[i].entry->flags & ACTIVE) {
-                       use_32bit = TRUE;
-                       break;
-               }
-       }
        return use_32bit;
 }
 
 /* Make sure there's at least one syscall enabled. */
 int validate_syscall_tables(void)
 {
-       unsigned int i, ret;
+       unsigned int ret;
 
        if (biarch == TRUE) {
                ret = validate_syscall_table_32();
@@ -197,11 +227,10 @@ int validate_syscall_tables(void)
        }
 
        /* non-biarch case*/
-       for_each_syscall(i) {
-               if (syscalls[i].entry->flags & ACTIVE)
-                       return TRUE;
-       }
-       return FALSE;
+       if (shm->nr_active_syscalls == 0)
+               return FALSE;
+       else
+               return TRUE;
 }
 
 static void check_syscall(struct syscall *entry)
@@ -271,13 +300,19 @@ void mark_all_syscalls_active(void)
 
        printf("Marking all syscalls as enabled.\n");
        if (biarch == TRUE) {
-               for_each_32bit_syscall(i)
+               for_each_32bit_syscall(i) {
                        syscalls_32bit[i].entry->flags |= ACTIVE;
-               for_each_64bit_syscall(i)
+                       activate_syscall32(i);
+               }
+               for_each_64bit_syscall(i) {
                        syscalls_64bit[i].entry->flags |= ACTIVE;
+                       activate_syscall64(i);
+               }
        } else {
-               for_each_syscall(i)
+               for_each_syscall(i) {
                        syscalls[i].entry->flags |= ACTIVE;
+                       activate_syscall(i);
+               }
        }
 }
 
@@ -324,7 +359,26 @@ static void clear_check_user_specified_arch(const char 
*arg, char **arg_name)
        }
 }
 
-static void toggle_syscall_biarch(const char *arg, unsigned char state)
+static void toggle_syscall_biarch_n(int calln, const struct syscalltable 
*table, bool onlyflag, bool doflag, bool state, void (*activate)(unsigned int), 
int arch_bits, const char *arg_name) {
+
+       if (calln != -1) {
+               validate_specific_syscall(table, calln);
+
+               if ((state == TRUE) && onlyflag && doflag) {
+                       table[calln].entry->flags |= ACTIVE;
+                       (*activate)(calln);
+               } else {
+                       table[calln].entry->flags |= TO_BE_DEACTIVATED;
+               }
+       }
+
+       if ((arch_bits != 0) && (calln != -1))
+               printf("[%d] Marking %d-bit syscall %s (%d) as to be 
%sabled.\n",
+                       getpid(), arch_bits, arg_name, calln,
+                       state ? "en" : "dis");
+}
+
+static void toggle_syscall_biarch(const char *arg, bool state)
 {
        int specific_syscall32 = 0;
        int specific_syscall64 = 0;
@@ -334,30 +388,14 @@ static void toggle_syscall_biarch(const char *arg, 
unsigned char state)
 
        check_user_specified_arch(arg, &arg_name, &only_64bit, &only_32bit);
 
-       specific_syscall64 = search_syscall_table(syscalls_64bit, 
max_nr_64bit_syscalls, arg_name);
-
        /* If we found a 64bit syscall, validate it. */
-       if (specific_syscall64 != -1) {
-               validate_specific_syscall(syscalls_64bit, specific_syscall64);
-
-               if ((state == TRUE) && only_64bit && do_64_arch)
-                       syscalls_64bit[specific_syscall64].entry->flags |= 
ACTIVE;
-               else
-                       syscalls_64bit[specific_syscall64].entry->flags |= 
TO_BE_DEACTIVATED;
-       }
+       specific_syscall64 = search_syscall_table(syscalls_64bit, 
max_nr_64bit_syscalls, arg_name);
+       toggle_syscall_biarch_n(specific_syscall64, syscalls_64bit, only_64bit, 
do_64_arch, state, &activate_syscall64, 0, arg_name);
 
        /* Search for and validate 32bit */
        specific_syscall32 = search_syscall_table(syscalls_32bit, 
max_nr_32bit_syscalls, arg_name);
-       if (specific_syscall32 != -1) {
-               validate_specific_syscall(syscalls_32bit, specific_syscall32);
+       toggle_syscall_biarch_n(specific_syscall32, syscalls_32bit, only_32bit, 
do_32_arch, state, &activate_syscall32, 0, arg_name);
 
-               if ((state == TRUE) && only_32bit && do_32_arch)
-                       syscalls_32bit[specific_syscall32].entry->flags |= 
ACTIVE;
-               else
-                       syscalls_32bit[specific_syscall32].entry->flags |= 
TO_BE_DEACTIVATED;
-       }
-
-       clear_check_user_specified_arch(arg, &arg_name);
 
        if ((!only_32bit) && (!only_64bit)) {
                printf("No idea what architecture for syscall (%s) is.\n", arg);
@@ -369,11 +407,11 @@ static void toggle_syscall_biarch(const char *arg, 
unsigned char state)
                exit(EXIT_FAILURE);
        }
 
-       /* biarch? */
        if ((specific_syscall64 != -1) && (specific_syscall32 != -1)) {
                printf("[%d] Marking syscall %s (64bit:%d 32bit:%d) as to be 
%sabled.\n",
-                       getpid(), arg, specific_syscall64, specific_syscall32,
+                       getpid(), arg_name, specific_syscall64, 
specific_syscall32,
                        state ? "en" : "dis");
+               clear_check_user_specified_arch(arg, &arg_name);
                return;
        }
 
@@ -381,6 +419,7 @@ static void toggle_syscall_biarch(const char *arg, unsigned 
char state)
                printf("[%d] Marking 64-bit syscall %s (%d) as to be 
%sabled.\n",
                        getpid(), arg, specific_syscall64,
                        state ? "en" : "dis");
+               clear_check_user_specified_arch(arg, &arg_name);
                return;
        }
 
@@ -388,11 +427,34 @@ static void toggle_syscall_biarch(const char *arg, 
unsigned char state)
                printf("[%d] Marking 32-bit syscall %s (%d) as to be 
%sabled.\n",
                        getpid(), arg, specific_syscall32,
                        state ? "en" : "dis");
+               clear_check_user_specified_arch(arg, &arg_name);
                return;
        }
+
+}
+
+static void toggle_syscall_n(int calln, bool state, const char *arg, const 
char *arg_name) {
+
+       if (calln == -1) {
+               printf("No idea what syscall (%s) is.\n", arg);
+               exit(EXIT_FAILURE);
+       }
+
+       validate_specific_syscall(syscalls, calln);
+
+       if (state == TRUE) {
+               syscalls[calln].entry->flags |= ACTIVE;
+               activate_syscall(calln);
+       } else {
+               syscalls[calln].entry->flags |= TO_BE_DEACTIVATED;
+       }
+
+       printf("[%d] Marking syscall %s (%d) as to be %sabled.\n",
+               getpid(), arg_name, calln,
+               state ? "en" : "dis");
 }
 
-void toggle_syscall(const char *arg, unsigned char state)
+void toggle_syscall(const char *arg, bool state)
 {
        int specific_syscall = 0;
        char * arg_name = NULL;
@@ -405,23 +467,8 @@ void toggle_syscall(const char *arg, unsigned char state)
        /* non-biarch case. */
        check_user_specified_arch(arg, &arg_name, NULL, NULL); //We do not care 
about arch here, just to get rid of arg flags.
        specific_syscall = search_syscall_table(syscalls, max_nr_syscalls, 
arg_name);
+       toggle_syscall_n(specific_syscall, state, arg, arg_name);
        clear_check_user_specified_arch(arg, &arg_name);
-
-       if (specific_syscall == -1) {
-               printf("No idea what syscall (%s) is.\n", arg_name);
-               exit(EXIT_FAILURE);
-       }
-
-       validate_specific_syscall(syscalls, specific_syscall);
-
-       if (state == TRUE)
-               syscalls[specific_syscall].entry->flags |= ACTIVE;
-       else
-               syscalls[specific_syscall].entry->flags |= TO_BE_DEACTIVATED;
-
-       printf("[%d] Marking syscall %s (%d) as to be %sabled.\n",
-               getpid(), arg, specific_syscall,
-               state ? "en" : "dis");
 }
 
 void deactivate_disabled_syscalls(void)
@@ -434,6 +481,7 @@ void deactivate_disabled_syscalls(void)
                for_each_64bit_syscall(i) {
                        if (syscalls_64bit[i].entry->flags & TO_BE_DEACTIVATED) 
{
                                syscalls_64bit[i].entry->flags &= 
~(ACTIVE|TO_BE_DEACTIVATED);
+                               deactivate_syscall64(i);
                                printf("[%d] Marked 64-bit syscall %s (%d) as 
deactivated.\n",
                                        getpid(), 
syscalls_64bit[i].entry->name, syscalls_64bit[i].entry->number);
                        }
@@ -441,6 +489,7 @@ void deactivate_disabled_syscalls(void)
                for_each_32bit_syscall(i) {
                        if (syscalls_32bit[i].entry->flags & TO_BE_DEACTIVATED) 
{
                                syscalls_32bit[i].entry->flags &= 
~(ACTIVE|TO_BE_DEACTIVATED);
+                               deactivate_syscall32(i);
                                printf("[%d] Marked 32-bit syscall %s (%d) as 
deactivated.\n",
                                        getpid(), 
syscalls_32bit[i].entry->name, syscalls_32bit[i].entry->number);
                        }
@@ -450,6 +499,7 @@ void deactivate_disabled_syscalls(void)
                for_each_syscall(i) {
                        if (syscalls[i].entry->flags & TO_BE_DEACTIVATED) {
                                syscalls[i].entry->flags &= 
~(ACTIVE|TO_BE_DEACTIVATED);
+                               deactivate_syscall(i);
                                printf("[%d] Marked syscall %s (%d) as 
deactivated.\n",
                                        getpid(), syscalls[i].entry->name, 
syscalls[i].entry->number);
                        }
@@ -516,6 +566,7 @@ static struct syscalltable * copy_syscall_table(struct 
syscalltable *from, unsig
        for (n = 0; n < nr; n++) {
                memcpy(copy + n , from[n].entry, sizeof(struct syscall));
                copy[n].number = n;
+               copy[n].active_number = 0;
                from[n].entry = &copy[n];
        }
        return from;
@@ -569,91 +620,46 @@ void select_syscall_tables(void)
 
 int setup_syscall_group(unsigned int group)
 {
-       struct syscalltable *newsyscalls;
-       struct syscalltable *newsyscalls32;
-       struct syscalltable *newsyscalls64;
-
        unsigned int i;
-       int count = 0, j = 0;
 
        if (biarch == TRUE) {
                for_each_32bit_syscall(i) {
                        if (syscalls_32bit[i].entry->group == group)
-                               count++;
+                               activate_syscall32(i);
                }
 
-               if (count == 0) {
+               if (shm->nr_active_32bit_syscalls == 0) {
                        printf("No 32-bit syscalls in group\n");
-                       goto try_64bit;
+               } else {
+                       printf("Found %d 32-bit syscalls in group\n", 
shm->nr_active_32bit_syscalls);
                }
 
-               newsyscalls32 = malloc(count * sizeof(struct syscalltable));
-               if (newsyscalls32 == NULL)
-                       return FALSE;
-
-               for_each_32bit_syscall(i) {
-                       if (syscalls_32bit[i].entry->group == group)
-                               newsyscalls32[j++].entry = 
syscalls_32bit[i].entry;
-               }
-
-               max_nr_32bit_syscalls = count;
-               syscalls_32bit = newsyscalls32;
-
-               printf("Found %d 32-bit syscalls in group\n", 
max_nr_32bit_syscalls);
-
-try_64bit:
                /* now the 64 bit table*/
-               count = 0, j = 0;
-
                for_each_64bit_syscall(i) {
                        if (syscalls_64bit[i].entry->group == group)
-                               count++;
+                               activate_syscall64(i);
                }
 
-               if (count == 0) {
+               if (shm->nr_active_64bit_syscalls == 0) {
                        printf("No 64-bit syscalls in group\n");
                        return FALSE;
+               } else {
+                       printf("Found %d 64-bit syscalls in group\n", 
shm->nr_active_64bit_syscalls);
                }
 
-               newsyscalls64 = malloc(count * sizeof(struct syscalltable));
-               if (newsyscalls64 == NULL)
-                       return FALSE;
-
-               for_each_64bit_syscall(i) {
-                       if (syscalls_64bit[i].entry->group == group)
-                               newsyscalls64[j++].entry = 
syscalls_64bit[i].entry;
-               }
-
-               max_nr_64bit_syscalls = count;
-               syscalls_64bit = newsyscalls64;
-               printf("Found %d 64-bit syscalls in group\n", 
max_nr_32bit_syscalls);
-
        } else {
                /* non-biarch case. */
-
                for_each_syscall(i) {
                        if (syscalls[i].entry->group == group)
-                               count++;
+                               activate_syscall(i);
                }
 
-               if (count == 0) {
+               if (shm->nr_active_syscalls == 0) {
                        printf("No syscalls found in group\n");
                        return FALSE;
+               } else {
+                       printf("Found %d syscalls in group\n", 
shm->nr_active_syscalls);
                }
-
-               newsyscalls = malloc(count * sizeof(struct syscalltable));
-               if (newsyscalls == NULL)
-                       exit(EXIT_FAILURE);
-
-               for_each_syscall(i) {
-                       if (syscalls[i].entry->group == group)
-                               newsyscalls[j++].entry = syscalls[i].entry;
-               }
-
-               max_nr_syscalls = count;
-               syscalls = newsyscalls;
-
-               printf("Found %d syscalls in group\n", max_nr_syscalls);
        }
 
        return TRUE;
@@ -685,16 +691,6 @@ const char * print_syscall_name(unsigned int callno, bool 
is32bit)
        return table[callno].entry->name;
 }
 
-// FIXME: in the biarch=TRUE case, we ignore 32bit for now
-static const char * lookup_name(unsigned int num)
-{
-       if (biarch == TRUE) {
-               return syscalls_64bit[num].entry->name;
-       }
-
-       return syscalls[num].entry->name;
-}
-
 void display_enabled_syscalls(void)
 {
        unsigned int i;
@@ -762,7 +758,6 @@ static bool is_syscall_net_related(const struct 
syscalltable *table, unsigned in
 
 void disable_non_net_syscalls(void)
 {
-       const char *syscallname;
        unsigned int i;
 
        printf("Disabling non networking related syscalls\n");
@@ -774,8 +769,8 @@ void disable_non_net_syscalls(void)
 
                        if (syscalls_64bit[i].entry->flags & ACTIVE) {
                                if (is_syscall_net_related(syscalls_64bit, i) 
== FALSE) {
-                                       syscallname = lookup_name(i);
-                                       toggle_syscall_biarch(syscallname, 
FALSE);
+                                       toggle_syscall_biarch_n(i, 
syscalls_64bit, FALSE, do_64_arch, FALSE,
+                                                               
&activate_syscall64, 64, syscalls_64bit[i].entry->name);
                                }
                        }
                }
@@ -786,8 +781,8 @@ void disable_non_net_syscalls(void)
 
                        if (syscalls_32bit[i].entry->flags & ACTIVE) {
                                if (is_syscall_net_related(syscalls_32bit, i) 
== FALSE) {
-                                       syscallname = 
syscalls_32bit[i].entry->name;
-                                       toggle_syscall_biarch(syscallname, 
FALSE);
+                                       toggle_syscall_biarch_n(i, 
syscalls_32bit, FALSE, do_32_arch, FALSE,
+                                                               
&activate_syscall32, 32, syscalls_32bit[i].entry->name);
                                }
                        }
                }
@@ -800,8 +795,7 @@ void disable_non_net_syscalls(void)
 
                        if (syscalls[i].entry->flags & ACTIVE) {
                                if (is_syscall_net_related(syscalls, i) == 
FALSE) {
-                                       syscallname = lookup_name(i);
-                                       toggle_syscall(syscallname, FALSE);
+                                       toggle_syscall_n(i, FALSE, 
syscalls[i].entry->name, syscalls[i].entry->name);
                                }
                        }
                }
@@ -815,8 +809,9 @@ void disable_non_net_syscalls(void)
 void enable_random_syscalls(void)
 {
        unsigned int i;
-       const char *syscallname;
-       unsigned int call, call32, call64;
+       unsigned int call, call32, call64, callnotfound;
+
+       callnotfound = (unsigned int)-1;
 
        if (random_selection_num == 0) {
                printf("-r 0 syscalls ? what?\n");
@@ -824,7 +819,7 @@ void enable_random_syscalls(void)
        }
 
        if (biarch == TRUE) {
-               if (random_selection_num > max_nr_64bit_syscalls) {
+               if ((random_selection_num > max_nr_64bit_syscalls) && 
do_64_arch) {
                        printf("-r val %d out of range (1-%d)\n", 
random_selection_num, max_nr_64bit_syscalls);
                        exit(EXIT_FAILURE);
                }
@@ -836,31 +831,72 @@ void enable_random_syscalls(void)
        }
 
        printf("Enabling %d random syscalls\n", random_selection_num);
-
+
        for (i = 0; i < random_selection_num; i++) {
 
 retry:
                if (biarch == TRUE) {
-                       call64 = rand() % max_nr_64bit_syscalls;
-                       syscallname = lookup_name(call64);
-                       call32 = search_syscall_table(syscalls_32bit, 
max_nr_32bit_syscalls, syscallname);
+                       call64 = callnotfound;
+                       call32 = callnotfound;
 
-                       if (validate_specific_syscall_silent(syscalls_64bit, 
call64) == FALSE)
-                               goto retry;
-                       if (validate_specific_syscall_silent(syscalls_32bit, 
call32) == FALSE)
-                               goto retry;
-
-                       if (no_files == TRUE) {
-                               if (is_syscall_net_related(syscalls_64bit, 
call64) == FALSE)
-                                       goto retry;
-                               if (is_syscall_net_related(syscalls_32bit, 
call32) == FALSE)
+                       //Search for 64 bit version
+                       if (do_64_arch) {
+                               call64 = rand() % max_nr_64bit_syscalls;
+                               if 
(validate_specific_syscall_silent(syscalls_64bit, call64) == FALSE)
                                        goto retry;
+
+                               if (no_files == TRUE)
+                                       if 
(is_syscall_net_related(syscalls_64bit, call64) == FALSE)
+                                               goto retry;
+
+                               if (syscalls_64bit[call64].entry->flags & 
TO_BE_DEACTIVATED)
+                                       goto try32bit;
+
+                               //If we got so far, then active it.
+                               toggle_syscall_biarch_n(i, syscalls_64bit, 
TRUE, do_64_arch, TRUE,
+                                                                
&activate_syscall64, 64, syscalls_64bit[call64].entry->name);
                        }
+try32bit:
+                       //Search for 32 bit version
+                       if (do_32_arch) {
+
+                               if (do_64_arch) {
+                                       call32 = 
search_syscall_table(syscalls_32bit, 
max_nr_32bit_syscalls,syscalls_64bit[call64].entry->name);
+                                       if (syscalls_64bit[call64].entry->flags 
& TO_BE_DEACTIVATED)
+                                               call64 = callnotfound; //mark 
as not found in order not to increment i.
+                               } else {
+                                       call32 = rand() % max_nr_32bit_syscalls;
+                               }
+
+                               if 
(validate_specific_syscall_silent(syscalls_32bit, call32) == FALSE) {
+                                       if (call64 == callnotfound)
+                                               goto retry;
+                                       else
+                                               continue;
+                               }
+
+                               if (no_files == TRUE)
+                                       if 
(is_syscall_net_related(syscalls_64bit, call64) == FALSE) {
+                                               if (call64 == callnotfound)
+                                                       goto retry;
+                                               else
+                                                       continue;
+                                       }
+
+                               if (syscalls_64bit[call64].entry->flags & 
TO_BE_DEACTIVATED) {
+                                       if (call64 == callnotfound)
+                                               goto retry;
+                                       else
+                                               continue;
+                               }
+
+                               //If we got so far, then active it.
+                               toggle_syscall_biarch_n(i, syscalls_32bit, 
TRUE, do_32_arch, TRUE,
+                                                                
&activate_syscall32, 32, syscalls_32bit[call32].entry->name);
+                       }
+
+
 
-                       if (syscalls_64bit[call64].entry->flags & 
TO_BE_DEACTIVATED)
-                               goto retry;
-                       if (syscalls_32bit[call32].entry->flags & 
TO_BE_DEACTIVATED)
-                               goto retry;
 
                } else {
                        call = rand() % max_nr_syscalls;
@@ -876,9 +912,7 @@ retry:
                        if (syscalls[call].entry->flags & TO_BE_DEACTIVATED)
                                goto retry;
 
-                       syscallname = lookup_name(call);
+                       toggle_syscall_n(call, FALSE, 
syscalls[call].entry->name, syscalls[call].entry->name);
                }
-
-               toggle_syscall(syscallname, TRUE);
        }
 }
diff --git a/trinity.c b/trinity.c
index 84d86ca..94535ac 100644
--- a/trinity.c
+++ b/trinity.c
@@ -69,6 +69,13 @@ static int create_shm(void)
 
        memset(shm->pids, EMPTY_PIDSLOT, sizeof(shm->pids));
 
+       shm->nr_active_syscalls = 0;
+       shm->nr_active_32bit_syscalls = 0;
+       shm->nr_active_64bit_syscalls = 0;
+       memset(shm->active_syscalls, 0, sizeof(shm->active_syscalls));
+       memset(shm->active_syscalls32, 0, sizeof(shm->active_syscalls32));
+       memset(shm->active_syscalls64, 0, sizeof(shm->active_syscalls64));
+
        /* Overwritten later in setup_shm_postargs if user passed -s */
        shm->seed = new_seed();
 
@@ -105,7 +112,7 @@ static int munge_tables(void)
        /* By default, all syscall entries will be disabled.
         * If we didn't pass -c, -x or -r, mark all syscalls active.
         */
-       if ((do_specific_syscall == FALSE) && (do_exclude_syscall == FALSE) && 
(random_selection == FALSE))
+       if ((do_specific_syscall == FALSE) && (do_exclude_syscall == FALSE) && 
(random_selection == FALSE) && (desired_group == GROUP_NONE))
                mark_all_syscalls_active();
 
        if (desired_group != GROUP_NONE) {
@@ -123,7 +130,6 @@ static int munge_tables(void)
        if (do_exclude_syscall == TRUE) {
                if (random_selection == FALSE)
                        mark_all_syscalls_active();
-
                deactivate_disabled_syscalls();
        }
 
@@ -228,7 +234,7 @@ int main(int argc, char* argv[])
                        printf("Unless you are running in a virtual machine, 
this could cause serious problems such as overwriting CMOS\n");
                        printf("or similar which could potentially make this 
machine unbootable without a firmware reset.\n\n");
                        printf("ctrl-c now unless you really know what you are 
doing.\n");
-                       for (i = 10; i > 0; i--) {
+                       for (i = 2; i > 0; i--) {
                                printf("Continuing in %d seconds.\r", i);
                                (void)fflush(stdout);
                                sleep(1);
-- 
1.8.4

--
To unsubscribe from this list: send the line "unsubscribe trinity" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to