Minix 3 version

This commit is contained in:
Philip Homburg 2008-10-02 13:45:46 +00:00
parent 659ab96c1f
commit 5b5b54c76c
19 changed files with 1830 additions and 118 deletions

View file

@ -1,25 +1,20 @@
#
# Makefile for the nooks.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
OBJ=systest.o fault_model.o extra.o db_sym.o db_disasm.o db_access.o read_nlist.o
OBJ_RND=rnd.o
OBJ_SOCKET=socket.o
O_TARGET := swifi.o
DEFINES=-DCONFIG_SWIFI
CFLAGS=$(DEFINES)
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
all: swifi rnd socket
export-objs = swifi-ksyms.o
swifi: $(OBJ)
$(CC) -o swifi $(OBJ)
obj-$(CONFIG_SWIFI) += db_sym.o db_disasm.o db_access.o \
random.o fault_model.o swifi-ksyms.o
rnd: $(OBJ_RND)
$(CC) -o $@ $(OBJ_RND)
# db_interface.o
include $(TOPDIR)/Rules.make
fastdep:
socket: $(OBJ_SOCKET)
$(CC) -o $@ $(OBJ_SOCKET)
clean:
rm -f swifi $(OBJ)

4
commands/swifi/do_swifi Normal file
View file

@ -0,0 +1,4 @@
#!/bin/sh
pid=`ps ax | grep fxp | grep usr.sbin | sed 's,^[ ]*,,;s,[ ].*,,`
echo "pid = $pid"
./swifi -f /usr/build/drivers/fxp/fxp $pid 26 100 4

View file

@ -0,0 +1,4 @@
#!/bin/sh
pid=`ps ax | grep fxp | grep usr.sbin | sed 's,^[ ]*,,;s,[ ].*,,`
echo "pid = $pid"
./swifi -f /usr/build/drivers/fxp/fxp $pid 8 100 4

250
commands/swifi/extra.c Normal file
View file

@ -0,0 +1,250 @@
/*
Declaration for Linux kernel compatibility
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include "extra.h"
pid_t victim_pid= -1;
char *victim_exe= NULL;
#define TRAP_BIT (0x80000000)
static struct nlist *exe_nlist;
static int exe_nlist_n;
/* unsigned long __get_free_page(int type) { assert(0); } */
/* void *kmalloc(size_t size, int type) { assert(0); } */
void free_page(unsigned long page) { assert(0); }
/* void kfree(void *mem) { assert(0); } */
void vfree(void *mem) { assert(0); }
size_t strncpy_from_user(char *addr, const char *user_name, size_t size)
{ assert(0); }
/* void lock_kernel(void) { assert(0); } */
/* void unlock_kernel(void) { assert(0); } */
void __asm__(char *str) { assert(0); }
extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
{ assert(0); }
#if 0
void kallsyms_sections(void *infop,
int (*fp)(void *token, const char *modname, const char *secname,
ElfW(Addr) secstart, ElfW(Addr) secend, ElfW(Word) secflags))
{ assert(0); }
#endif
unsigned long __generic_copy_to_user(void *x, const void *y, unsigned long z)
{ assert(0); }
unsigned long __generic_copy_from_user(void *x, const void *y, unsigned long z)
{ assert(0); }
/* void read_lock(struct lock *lock) { assert(0); } */
/* void read_unlock(struct lock *lock) { assert(0); } */
void udelay(unsigned long usecs) { assert(0); }
int copy_to_user(void * result_record, void *res, size_t size)
{
memcpy(result_record, res, size);
return 0;
}
void panic(char *str) { assert(0); }
void printk(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
int kallsyms_address_to_symbol(db_expr_t off,
const char * *mod_name, unsigned long *mod_start, unsigned long *mod_end,
const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end,
const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end)
{
static char name[sizeof(((struct nlist *)0)->n_name)+1];
int i;
unsigned long btext, etext;
struct nlist *below, *above;
off &= ~TRAP_BIT;
load_nlist(victim_exe, &btext, &etext);
below= above= NULL;
for (i= 0; i<exe_nlist_n; i++)
{
if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
continue;
if (exe_nlist[i].n_value <= off)
{
if (!below || exe_nlist[i].n_value > below->n_value)
below= &exe_nlist[i];
}
if (exe_nlist[i].n_value > off)
{
if (!above || exe_nlist[i].n_value < above->n_value)
above= &exe_nlist[i];
}
}
#if 0
if (below)
{
printf("found '%.*s' at 0x%x\n", sizeof(below->n_name),
below->n_name, below->n_value);
}
if (above)
{
printf("found '%.*s' at 0x%x\n", sizeof(above->n_name),
above->n_name, above->n_value);
}
#endif
btext |= TRAP_BIT;
etext |= TRAP_BIT;
*mod_name = victim_exe;
*mod_start = btext;
*mod_end = etext;
*sec_name = ".text";
*sec_start = btext;
*sec_end = etext;
assert(below && above);
memcpy(name, below->n_name, sizeof(below->n_name));
name[sizeof(below->n_name)]= '\0';
*sym_name= name;
*sym_start= below->n_value | TRAP_BIT;
*sym_end= above->n_value | TRAP_BIT;
return 1;
}
struct module *module_list;
struct task_struct *task_list;
struct lock tasklist_lock;
unsigned long text_read_ul(void *addr)
{
int i;
unsigned long value;
for (i= 0; i<sizeof(value); i++)
{
((unsigned char *)&value)[i]= text_read_ub((char *)addr+i);
}
return value;
}
unsigned char text_read_ub(void *addr)
{
int v;
unsigned long vaddr;
vaddr= (unsigned long)addr;
vaddr &= ~TRAP_BIT;
v= ptrace(T_READB_INS, victim_pid, vaddr, 0);
if (v < 0)
{
fprintf(stderr,
"text_read_ub: trace T_READB_INS failed on pid %d, addr 0x%x: %s\n",
victim_pid, vaddr, strerror(errno));
exit(1);
}
return v;
}
void text_write_ul(void *addr, unsigned long value)
{
int i;
for (i= 0; i<sizeof(value); i++)
{
text_write_ub((char *)addr+i, ((unsigned char *)&value)[i]);
}
}
void text_write_ub(void *addr, unsigned char value)
{
int v;
unsigned long vaddr;
vaddr= (unsigned long)addr;
vaddr &= ~TRAP_BIT;
v= ptrace(T_WRITEB_INS, victim_pid, vaddr, value);
if (v < 0)
{
fprintf(stderr,
"text_read_ub: trace T_WRITEB_INS failed on pid %d, addr 0x%x: %s\n",
victim_pid, vaddr, strerror(errno));
exit(1);
}
}
void load_nlist(exe_name, btextp, etextp)
char *exe_name;
unsigned long *btextp;
unsigned long *etextp;
{
int i;
unsigned long btext, etext;
if (!exe_nlist)
{
exe_nlist_n= read_nlist(exe_name, &exe_nlist);
if (exe_nlist_n <= 0)
{
if (exe_nlist_n == -1)
{
fprintf(stderr,
"error reading name list from '%s': %s\n",
exe_name, strerror(errno));
}
else
fprintf(stderr, "no name list in '%s'\n",
exe_name);
exit(1);
}
}
if (!btextp && !etextp)
return;
etext= 0;
btext= (unsigned long)-1;
for (i= 0; i<exe_nlist_n; i++)
{
if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
continue;
if (exe_nlist[i].n_value < btext)
btext= exe_nlist[i].n_value;
if (exe_nlist[i].n_value > etext)
etext= exe_nlist[i].n_value;
}
if (btext >= etext)
{
fprintf(stderr, "Bad btext (0x%x) or etext (0x%x) in %d\n",
btext, etext, exe_name);
exit(1);
}
btext |= TRAP_BIT;
etext |= TRAP_BIT;
if (btextp)
*btextp= btext;
if (etextp)
*etextp= etext;
}

96
commands/swifi/extra.h Normal file
View file

@ -0,0 +1,96 @@
/*
Compatibility with the linux kernel environment
*/
#include <a.out.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#if 0
struct module
{
struct module *next;
char *name;
};
extern struct module *module_list;
#endif
struct thread
{
unsigned long esp;
};
struct task_struct
{
struct thread thread;
struct task_struct *next;
};
unsigned long __get_free_page(int type);
void *kmalloc(size_t size, int type);
#define GFP_KERNEL 1
void free_page(unsigned long page);
void kfree(void *mem);
void vfree(void *mem);
size_t strncpy_from_user(char *addr, const char *user_name, size_t size);
void lock_kernel(void);
void unlock_kernel(void);
void __asm__(char *str);
#define for_each_task(t) for(t= task_list; t; t=t->next)
extern struct task_struct *task_list;
typedef struct { int foo; } pgprot_t;
extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot);
#define ElfW(type) Elf_ ## type
typedef unsigned long Elf_Addr;
typedef unsigned long Elf_Word;
void kallsyms_sections(void *infop,
int (*fp)(void *token, const char *modname, const char *secname,
ElfW(Addr) secstart, ElfW(Addr) secend, ElfW(Word) secflags));
unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
struct lock { int dummy; };
extern struct lock tasklist_lock;
void read_lock(struct lock *lock);
void read_unlock(struct lock *lock);
void udelay(unsigned long usecs);
int copy_to_user(void * result_record, void *res, size_t size);
void panic(char *str);
#define PAGE_SIZE (0x1000)
#define PAGE_MASK (0x0fff)
#define PAGE_OFFSET 0 /* What does this do? */
#define TASK_SIZE 0 /* What does this do? */
void printk(char *fmt, ...);
#include "ddb.h"
#include "db_machdep.h"
int kallsyms_address_to_symbol(db_expr_t off,
const char * *mod_name, unsigned long *mod_start, unsigned long *mod_end,
const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end,
const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end);
int read_nlist(const char *filenamer, struct nlist **nlist_table);
unsigned long text_read_ul(void *addr);
unsigned char text_read_ub(void *addr);
void text_write_ul(void *addr, unsigned long value);
void text_write_ub(void *addr, unsigned char value);
extern pid_t victim_pid;
extern char *victim_exe;
void load_nlist(char *exe_name, unsigned long *btextp, unsigned long *etextp);

View file

@ -44,6 +44,7 @@
* - use after free
*/
#if 0
#include <linux/kernel.h>
#include <linux/kallsyms.h>
#include <linux/module.h>
@ -54,10 +55,13 @@
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/page.h>
#endif
#include "ddb.h"
#include "db_sym.h"
#include "swifi.h"
#include "extra.h"
#define CRASH_INTERVAL 8192
#define FI_MASK 0xfff
@ -75,7 +79,7 @@ unsigned long faultType;
unsigned long numFaults;
char *crashAddr=0; /* track current malloc */
int crashToggle=1;
int text_fault(struct module * module, pswifi_result_t res);
int text_fault(char *mod_name, pswifi_result_t res);
int stack_fault(pswifi_result_t res);
int heap_fault(pswifi_result_t res);
int direct_fault(int fault_address, int fault_content, pswifi_result_t res);
@ -90,12 +94,15 @@ do { \
printk( KERN_ALERT "SWIFI: " fmt, ## args); \
} while (0)
#else
#define PDEBUG(fmt, args...)
#include <stdio.h>
#define PDEBUG(args) /* (printf args) */
#endif
#define inline
#ifdef CONFIG_SWIFI
#if 0
static inline long
get_mod_name(const char *user_name, char **buf)
{
@ -125,6 +132,7 @@ put_mod_name(char *buf)
{
free_page((unsigned long)buf);
}
#endif
long
sys_inject_fault(char * module_name,
@ -138,7 +146,9 @@ sys_inject_fault(char * module_name,
unsigned long fault_address = 0;
unsigned long fault_data = 0 ;
char * kern_name = NULL;
#if 0
struct module * mod = NULL;
#endif
int found = 0;
pswifi_result_t res = NULL;
@ -146,27 +156,30 @@ sys_inject_fault(char * module_name,
result = -E2BIG;
goto Cleanup;
}
res = (pswifi_result_t) kmalloc((1+argNumFaults) * sizeof(swifi_result_t),
GFP_KERNEL);
res = (pswifi_result_t) malloc((1+argNumFaults) * sizeof(swifi_result_t));
if (res == NULL) {
result = -ENOMEM;
goto Cleanup;
}
memset(res, 0, (1 + argNumFaults) * sizeof(swifi_result_t));
//
/*
// Capture the name of the module from usermode
//
*/
#if 0
result = get_mod_name(module_name, &kern_name);
if (result < 0) {
goto Cleanup;
}
#endif
kern_name= module_name;
#if 0
lock_kernel();
for (mod = module_list; mod ; mod = mod->next) {
@ -180,6 +193,7 @@ sys_inject_fault(char * module_name,
result = -ENOENT;
goto Cleanup;
}
#endif
numFaults = argNumFaults;
faultType = argFaultType;
@ -204,16 +218,16 @@ sys_inject_fault(char * module_name,
} else if (faultType == DIRECT_FAULT) {
fault_address = numFaults;
fault_data = randomSeed;
PDEBUG("sys inject fault, type %ld, addr=%lx, flip bit%lx\n",
faultType, fault_address, fault_data);
PDEBUG(("sys inject fault, type %ld, addr=%lx, flip bit%lx\n",
faultType, fault_address, fault_data));
} else if (faultType == DIRECT_FAULT1) {
fault_address = numFaults;
fault_data = randomSeed;
PDEBUG("sys inject fault, type %ld, addr=%lx, zero bytes %lx\n",
faultType, fault_address, fault_data);
PDEBUG(("sys inject fault, type %ld, addr=%lx, zero bytes %lx\n",
faultType, fault_address, fault_data));
} else {
PDEBUG("sys inject fault, type %ld, seed=%ld, fault=%ld, config=%ld\n",
faultType, randomSeed, numFaults, config);
PDEBUG(("sys inject fault, type %ld, seed=%ld, fault=%ld\n",
faultType, randomSeed, numFaults));
}
faultInjected=1;
@ -232,7 +246,7 @@ sys_inject_fault(char * module_name,
switch(faultType)
{
case TEXT_FAULT:
result = text_fault(mod, res);
result = text_fault(module_name, res);
break;
case STACK_FAULT:
result = stack_fault(res);
@ -249,7 +263,7 @@ sys_inject_fault(char * module_name,
case LOOP_FAULT:
case INTERFACE_FAULT:
case IRQ_FAULT:
result = text_fault(mod, res);
result = text_fault(module_name, res);
break;
case FREE_FAULT:
case BCOPY_FAULT:
@ -295,36 +309,38 @@ sys_inject_fault(char * module_name,
addr1 = (unsigned long *) 0xf0212000;
addr2 = (unsigned long *) 0xf0212010;
PDEBUG("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2);
PDEBUG(("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2));
__asm__ ("movl $0xf0212000, %eax\n\t" \
"movl $6, 0(%eax)\n\t" \
"movl $6, 4(%eax)\n\t");
addr1 = (unsigned long *) 0xf0212000;
addr2 = (unsigned long *) 0xf0212010;
PDEBUG("after injecting fault\n");
PDEBUG("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2);
PDEBUG(("after injecting fault\n"));
PDEBUG(("%p=%lx, %p=%lx\n", addr1, *addr1, addr2, *addr2));
result = 0;
break;
}
case DEBUGGER_FAULT:
PDEBUG("Debugger fault");
PDEBUG(("Debugger fault"));
__asm__ ("movl %cr4, %ecx\n\t" \
"movl $42, %ecx; .byte 0x0f, 0x32\n\t" \
"movl $377, %ecx; .byte 0x0f, 0x32\n\t");
result = 0;
break;
default: PDEBUG("unknown fault type %ld\n", faultType); break;
default: PDEBUG(("unknown fault type %ld\n", faultType)); break;
}
if (copy_to_user(result_record, res, argNumFaults * sizeof(swifi_result_t))) {
result = -EFAULT;
}
Cleanup:
#if 0
if (kern_name != NULL) {
put_mod_name(kern_name);
}
#endif
if (res != NULL) {
kfree(res);
free(res);
}
return (result);
@ -334,10 +350,10 @@ int while1(void)
{
int i=0;
PDEBUG("entering into while 1 loop\n");
PDEBUG(("entering into while 1 loop\n"));
while(1) {
udelay(20000);
PDEBUG("delay %4d secs, cpl=0x%x, ipend=0x%x\n", i+=5, 20, 30);
PDEBUG(("delay %4d secs, cpl=0x%x, ipend=0x%x\n", i+=5, 20, 30));
if(i>(100 * 2500))
break;
}
@ -353,7 +369,7 @@ int direct_fault(int fault_address, int fault_content, pswifi_result_t res)
addr = (unsigned long *) (PAGE_OFFSET + fault_address);
PDEBUG("%p:0x%lx => ", addr, *addr);
PDEBUG(("%p:0x%lx => ", addr, *addr));
flip_bit = 1 << fault_content;
@ -364,7 +380,7 @@ int direct_fault(int fault_address, int fault_content, pswifi_result_t res)
if (injectFault) {
*addr = (*addr) ^ flip_bit;
}
PDEBUG("%lx\n", *addr);
PDEBUG(("%lx\n", *addr));
return(0);
}
@ -375,7 +391,7 @@ int direct_fault1(int fault_address, int fault_content, pswifi_result_t res)
addr = (unsigned long *) (PAGE_OFFSET + fault_address);
PDEBUG("%p:%lx => ", addr, *addr);
PDEBUG(("%p:%lx => ", addr, *addr));
data = *addr;
@ -398,7 +414,7 @@ int direct_fault1(int fault_address, int fault_content, pswifi_result_t res)
*addr = data;
}
PDEBUG("%lx\n", *addr);
PDEBUG(("%lx\n", *addr));
return(0);
@ -407,7 +423,9 @@ int direct_fault1(int fault_address, int fault_content, pswifi_result_t res)
/*
#include <linux/sched.h>
*/
#define MAX_NUM_TASKS 20
@ -421,14 +439,18 @@ find_task(void)
do {
#if 0
read_lock(&tasklist_lock);
#endif
for_each_task(task) {
if (--i == 0) {
result = task;
break;
}
}
#if 0
read_unlock(&tasklist_lock);
#endif
} while ((i > 0) && (i != j));
return(result);
@ -450,15 +472,15 @@ stack_fault(pswifi_result_t res)
size = (unsigned long) task + TASK_SIZE - task->thread.esp;
PDEBUG("stack range=%lx-%lx\n",
PDEBUG(("stack range=%lx-%lx\n",
(unsigned long) task->thread.esp,
(unsigned long) task + TASK_SIZE);
(unsigned long) task + TASK_SIZE));
addr = (unsigned long *) ((long) task->thread.esp +
(random()&~0x3)%size);
taddr=(unsigned long) addr;
flip_bit = random() & 0x1f;
PDEBUG("%lx:%lx flip bit %d => ", taddr, *addr, flip_bit);
PDEBUG(("%lx:%lx flip bit %d => ", taddr, *addr, flip_bit));
flip_bit = 1 << flip_bit;
res[count].address = taddr;
res[count].old = *addr;
@ -466,17 +488,18 @@ stack_fault(pswifi_result_t res)
if (injectFault) {
*addr = ((*addr)^flip_bit);
}
PDEBUG("%lx\n", *addr);
PDEBUG(("%lx\n", *addr));
count++;
}
return(0);
}
//
/*
// Instead of dealing with heaps directly, we look at the area cache of pages
// and vm pages and find an address there.
//
*/
int heap_fault(pswifi_result_t res)
@ -538,8 +561,8 @@ do_fault_copy_from_user (void *kaddr, const void *udaddr, unsigned long len,
i = random() & 0xc00;
}
}
PDEBUG("copyin: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n",
udaddr, kaddr, len, i, crashInterval, faultInjected);
PDEBUG(("copyin: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n",
udaddr, kaddr, len, i, crashInterval, faultInjected));
if (faultInjected++ <numFaults) {
len += i;
} else {
@ -581,8 +604,8 @@ do_fault_copy_to_user(void *udaddr, const void *kaddr, unsigned long len,
i = random() & 0xc00;
}
}
PDEBUG("copyout: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n",
kaddr, udaddr, len, i, crashInterval, faultInjected);
PDEBUG(("copyout: %p to %p, len=%ld overrun=%d, Intvl=%ld, inj=%ld\n",
kaddr, udaddr, len, i, crashInterval, faultInjected));
if (faultInjected++ <numFaults) {
len+=i;
} else {
@ -642,8 +665,8 @@ swifi_memcpy_fn (void *to, void *from, size_t len)
}
}
PDEBUG("memcpy: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n",
from, to, len, i, crashInterval, faultInjected);
PDEBUG(("memcpy: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n",
from, to, len, i, crashInterval, faultInjected));
if(faultInjected++ <numFaults) len+=i;
else faultInjected=0;
i=1;
@ -680,8 +703,8 @@ swifi_memmove_fn (void *to, void *from, size_t len)
}
}
PDEBUG("memmove: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n",
from, to, len, i, crashInterval, faultInjected);
PDEBUG(("memmove: %p to %p, len=%d overrun=%d, Intvl=%ld, inj=%ld\n",
from, to, len, i, crashInterval, faultInjected));
if(faultInjected++ <numFaults) len+=i;
else faultInjected=0;
i=1;
@ -723,8 +746,8 @@ do_fault_kfree(void *addr, void (* kfree_fn)(const void *))
/* alternate between premature freeing and non-free */
if(crashToggle) {
if(crashAddr) {
PDEBUG("malloc : freeing %p prematurely\n",
crashAddr);
PDEBUG(("malloc : freeing %p prematurely\n",
crashAddr));
kfree_fn(crashAddr);
kfree_fn(addr);
crashAddr=0;
@ -736,7 +759,7 @@ do_fault_kfree(void *addr, void (* kfree_fn)(const void *))
}
}
} else {
PDEBUG("free: don't free %p\n", addr);
PDEBUG(("free: don't free %p\n", addr));
if(faultInjected++ > numFaults) {
faultInjected=0;
}
@ -752,11 +775,13 @@ do_fault_kfree(void *addr, void (* kfree_fn)(const void *))
}
}
#if 0
void
swifi_kfree(const void *addr)
{
do_fault_kfree((void *) addr, kfree);
}
#endif
void do_vfree(const void * addr)
@ -782,7 +807,7 @@ do_fault_kmalloc(size_t size,
if (faultInjected && (faultType==ALLOC_FAULT)) {
crashCount++;
if(crashCount>=crashInterval) {
PDEBUG("kmalloc : returning null\n");
PDEBUG(("kmalloc : returning null\n"));
crashCount=0;
crashInterval = CRASH_INTERVAL + (random()&FI_MASK);
if (faultInjected++ > numFaults) {
@ -797,11 +822,13 @@ do_fault_kmalloc(size_t size,
}
#if 0
void *
swifi_kmalloc(size_t size, int flags)
{
return(do_fault_kmalloc(size, flags, kmalloc));
}
#endif
@ -815,7 +842,7 @@ void * do_fault_vmalloc(unsigned long size,
if (faultInjected && (faultType==ALLOC_FAULT)) {
crashCount++;
if(crashCount>=crashInterval) {
PDEBUG("vmalloc : returning null\n");
PDEBUG(("vmalloc : returning null\n"));
crashCount=0;
crashInterval = CRASH_INTERVAL + (random()&FI_MASK);
if (faultInjected++ > numFaults) {
@ -836,6 +863,7 @@ swifi___vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
#if 0
typedef struct section_callback {
const char * module_name;
const char * section_name;
@ -861,22 +889,20 @@ text_section_callback(void *token,
}
return(0);
}
#endif
int text_fault(struct module * mod, pswifi_result_t res)
int text_fault(char *mod_name, pswifi_result_t res)
{
unsigned long *addr, text_size, offset, page, taddr;
unsigned long btext, etext;
int count, flip_bit=0, len, rc;
unsigned char *c;
#if 0
struct module * module;
section_callback_t info;
//
#endif
#define MAX_NUM_MODULES 10
@ -885,21 +911,30 @@ int text_fault(struct module * mod, pswifi_result_t res)
for(count=0; count<numFaults; count++) {
int i = 1 + (random() % MAX_NUM_MODULES);
int j = i;
#if 0
module = mod;
#endif
#if 0
info.module_name = module->name;
info.module_name = "<module-name>";
info.section_name = ".text";
kallsyms_sections(&info, text_section_callback);
if (info.sec_start == 0 ) {
return(-1);
}
#endif
load_nlist(mod_name, &btext, &etext);
#if 0
btext = info.sec_start;
etext = info.sec_end;
#endif
text_size = etext - btext;
PDEBUG("text=%lx-%lx, size=%lx\n", btext, etext, text_size);
PDEBUG(("text=%lx-%lx, size=%lx\n", btext, etext, text_size));
addr = (unsigned long *)
(btext + ((unsigned long) (random()&~0xf) % text_size));
@ -923,7 +958,11 @@ int text_fault(struct module * mod, pswifi_result_t res)
continue;
}
}
PDEBUG("target addr=%lx, instr addr=%p, %lx=>", taddr, addr, *addr);
printf("len = %d\n", len);
PDEBUG(("target addr=%lx, instr addr=%p, %lx=>", taddr, addr,
text_read_ul(addr)));
offset = (unsigned long) addr&PAGE_MASK;
page = (unsigned long) addr&~PAGE_MASK;
@ -933,19 +972,19 @@ int text_fault(struct module * mod, pswifi_result_t res)
*/
res[count].address = taddr;
res[count].old = *addr;
res[count].new = *addr;
res[count].old = text_read_ul(addr);
res[count].new = text_read_ul(addr);
if (faultType==TEXT_FAULT) {
flip_bit = random() & 0x1f;
PDEBUG("flip bit %d => ", flip_bit);
PDEBUG(("flip bit %d => ", flip_bit));
flip_bit = 1 << flip_bit;
res[count].new = (*addr) ^ flip_bit;
res[count].new = text_read_ul(addr) ^ flip_bit;
if (injectFault) {
*addr = ((*addr)^flip_bit);
text_write_ul(addr, text_read_ul(addr)^flip_bit);
}
} else if (faultType==NOP_FAULT ||
@ -961,7 +1000,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
((unsigned char *) &res[count].new)[j] = NOP;
}
if (injectFault) {
*c=NOP;
text_write_ub(c, NOP);
}
c++;
@ -971,7 +1010,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
int prefix;
c=(unsigned char *) addr;
do {
switch (*c) {
switch (text_read_ub(c)) {
case 0x66: case 0x67: case 0x26: case 0x36:
case 0x2e: case 0x3e: case 0x64: case 0x65:
case 0xf0: case 0xf2: case 0xf3:
@ -985,35 +1024,56 @@ int text_fault(struct module * mod, pswifi_result_t res)
c++;
}
} while (prefix);
if(*c>=0xd8 && *c<=0xdf) {
if(text_read_ub(c)>=0xd8 && text_read_ub(c)<=0xdf) {
/* don't mess with fp instruction, yet.
* but there shouldn't be any fp instr in kernel.
*/
PDEBUG("floating point instruction, bailing out\n");
PDEBUG(("floating point instruction, bailing out\n"));
i--;
continue;
} else if(*c==0x0f) {
} else if(text_read_ub(c)==0x0f) {
c++;
}
if(*c==0x0f) {
if(text_read_ub(c)==0x0f) {
c++;
}
c++;
len = len-((long) c - (long) addr);
if (len == 0)
{
printf("tex_fault: len = %d\n", len);
count--;
continue;
}
if (len == 0)
{
int i;
printf(
"text_fault: bad length at address 0x%x, c = 0x%x, fault type %d\n",
addr, c, faultType);
printf("bytes:");
for (i= 0; i<16; i++)
printf(" 0x%02x", text_read_ub((char *)addr+i));
printf("\n");
abort();
*(int *)-4 = 0;
}
flip_bit = random() % (len*8);
PDEBUG("flip bit %d (len=%d) => ", flip_bit, len);
PDEBUG(("flip bit %d (len=%d) => ", flip_bit, len));
for(j=0; j<len; j++) {
/* go to the right byte */
if(flip_bit<8) {
flip_bit = 1 << flip_bit;
if (j < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[j] = (*c) ^ flip_bit;
((unsigned char *) &res[count].new)[j] =
(text_read_ub(c) ^ flip_bit);
}
if (injectFault) {
*c=(*c^flip_bit);
text_write_ub(c, (text_read_ub(c)^flip_bit));
}
j=len;
@ -1029,7 +1089,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
int prefix;
c=(unsigned char *) addr;
do {
switch (*c) {
switch (text_read_ub(c)) {
case 0x66: case 0x67: case 0x26: case 0x36:
case 0x2e: case 0x3e: case 0x64: case 0x65:
case 0xf0: case 0xf2: case 0xf3:
@ -1043,21 +1103,21 @@ int text_fault(struct module * mod, pswifi_result_t res)
c++;
}
} while (prefix);
if(*c>=0xd8 && *c<=0xdf) {
if(text_read_ub(c)>=0xd8 && text_read_ub(c)<=0xdf) {
/* don't mess with fp instruction, yet */
PDEBUG("floating point instruction, bailing out\n");
PDEBUG(("floating point instruction, bailing out\n"));
i--;
continue;
} else if(*c==0x0f) {
} else if(text_read_ub(c)==0x0f) {
c++;
}
if(*c==0x0f) {
if(text_read_ub(c)==0x0f) {
c++;
}
c++;
len = len-((long) c - (long) addr);
flip_bit = random() % (len*8-4);
PDEBUG("flip bit %d (len=%d) => ", flip_bit, len);
PDEBUG(("flip bit %d (len=%d) => ", flip_bit, len));
/* mod/rm byte is special */
@ -1066,11 +1126,11 @@ int text_fault(struct module * mod, pswifi_result_t res)
rc = c - (unsigned char *) addr;
if (rc < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[rc] = (*c) ^ flip_bit;
((unsigned char *) &res[count].new)[rc] = text_read_ub(c) ^ flip_bit;
}
if (injectFault) {
*c=(*c^flip_bit);
text_write_ub(c, text_read_ub(c)^flip_bit);
}
}
@ -1084,11 +1144,12 @@ int text_fault(struct module * mod, pswifi_result_t res)
rc = (c - (unsigned char *) addr);
if (rc < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[rc] = (*c) ^ flip_bit;
((unsigned char *) &res[count].new)[rc] =
text_read_ub(c) ^ flip_bit;
}
if (injectFault) {
*c=(*c^flip_bit);
text_write_ub(c, text_read_ub(c)^flip_bit);
}
j=len;
@ -1099,7 +1160,7 @@ int text_fault(struct module * mod, pswifi_result_t res)
} else if(faultType==LOOP_FAULT) {
c=(unsigned char *) addr;
/* replace rep with repe, and vice versa */
if(*c==0xf3) {
if(text_read_ub(c)==0xf3) {
if (j < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[j] = NOP;
}
@ -1110,81 +1171,82 @@ int text_fault(struct module * mod, pswifi_result_t res)
}
if (injectFault) {
*c=0xf2;
text_write_ub(c, 0xf2);
}
} else if(*c==0xf2) {
} else if(text_read_ub(c)==0xf2) {
rc = (c - (unsigned char *) addr);
if (rc < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[rc] = 0xf3;
}
if (injectFault) {
*c=0xf3;
text_write_ub(c, 0xf3);
}
} else if( ((*c)&0xf0)==0x70 ) {
} else if( (text_read_ub(c)&0xf0)==0x70 ) {
/* if we've jxx imm8 instruction,
* incl even byte instruction, eg jo (70) to jno (71)
* decl odd byte instruction, eg jnle (7f) to jle (7e)
*/
if(*c%2 == 0) {
if(text_read_ub(c)%2 == 0) {
rc = (c - (unsigned char *) addr);
if (rc < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[rc] = (*c) + 1;
((unsigned char *) &res[count].new)[rc] = text_read_ub(c) + 1;
}
if (injectFault) {
*c = *c+1;
text_write_ub(c, text_read_ub(c)+1);
}
} else {
rc = (c - (unsigned char *) addr);
if (rc < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[rc] = (*c) - 1;
((unsigned char *) &res[count].new)[rc] = text_read_ub(c) - 1;
}
if (injectFault) {
*c = *c-1;
text_write_ub(c, text_read_ub(c)-1);
}
}
} else if(*c==0x66 || *c==0x67) { /* override prefix */
} else if(text_read_ub(c)==0x66 || text_read_ub(c)==0x67) {
/* override prefix */
c++;
} else if(*(c++)==0xf && ((*c)&0xf0)==0x80 ) {
} else if(text_read_ub(c++)==0xf && (text_read_ub(c)&0xf0)==0x80 ) {
/* if we've jxx imm16/32 instruction,
* incl even byte instruction, eg jo (80) to jno (81)
* decl odd byte instruction, eg jnle (8f) to jle (8e)
*/
if(*c%2 == 0) {
if(text_read_ub(c)%2 == 0) {
rc = (c - (unsigned char *) addr);
if (rc < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[rc] = (*c) + 1;
((unsigned char *) &res[count].new)[rc] = text_read_ub(c) + 1;
}
if (injectFault) {
*c = *c+1;
text_write_ub(c, text_read_ub(c)+1);
}
} else {
rc = (c - (unsigned char *) addr);
if (rc < sizeof(unsigned long)) {
((unsigned char *) &res[count].new)[rc] = (*c) -1;
((unsigned char *) &res[count].new)[rc] = text_read_ub(c) -1;
}
if (injectFault) {
*c = *c-1;
text_write_ub(c, text_read_ub(c)-1);
}
}
}
}
PDEBUG("%lx\n", *addr);
PDEBUG(("%lx\n", text_read_ul(addr)));
}
return(0);
}
#else // CONFIG_SWIFI
#else /* CONFIG_SWIFI */
long
sys_inject_fault(char * module_name,
@ -1197,5 +1259,4 @@ sys_inject_fault(char * module_name,
return(0);
}
#endif // CONFIG_SWIFI
#endif /* CONFIG_SWIFI */

329
commands/swifi/read_nlist.c Normal file
View file

@ -0,0 +1,329 @@
/*
read_nlist.c
Read the symbol table of an executable into memory.
Created: Mar 6, 1992 by Philip Homburg
*/
#include <sys/types.h>
#include <assert.h>
#include <a.out.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "extra.h"
#define USE_OLD_NLIST 1
static u16_t le16 _ARGS(( u16_t *word_p ));
static u32_t le32 _ARGS(( u32_t *word_p ));
static u16_t be16 _ARGS(( u16_t *word_p ));
static u32_t be32 _ARGS(( u32_t *word_p ));
static u16_t le16(word_p)
u16_t *word_p;
{
return (((u8_t *)word_p)[0] << 0) | (((u8_t *)word_p)[1] << 8);
}
static u16_t be16(word_p)
u16_t *word_p;
{
return (((u8_t *)word_p)[1] << 0) | (((u8_t *)word_p)[0] << 8);
}
static u32_t le32(dword_p)
u32_t *dword_p;
{
return le16(&((u16_t *)dword_p)[0]) |
((u32_t)le16(&((u16_t *)dword_p)[1]) << 16);
}
static u32_t be32(dword_p)
u32_t *dword_p;
{
return be16(&((u16_t *)dword_p)[1]) |
((u32_t)be16(&((u16_t *)dword_p)[0]) << 16);
}
#ifndef USE_OLD_NLIST
struct old_nlist
{
char n_name[8];
long n_value;
unsigned char n_sclass;
unsigned char n_numaux;
unsigned char n_type;
};
/* Low bits of storage class (section). */
#define O_N_SECT 07 /* section mask */
#define O_N_UNDF 00 /* undefined */
#define O_N_ABS 01 /* absolute */
#define O_N_TEXT 02 /* text */
#define O_N_DATA 03 /* data */
#define O_N_BSS 04 /* bss */
#define O_N_COMM 05 /* (common) */
/* High bits of storage class. */
#define O_N_CLASS 0370 /* storage class mask */
#define O_C_NULL
#define O_C_EXT 0020 /* external symbol */
#define O_C_STAT 0030 /* static */
#endif
int read_nlist(filename, nlist_table)
const char *filename;
struct nlist **nlist_table;
{
int r, n_entries, save_err;
u32_t (*cnv32) _ARGS(( u32_t *addr ));
u16_t (*cnv16) _ARGS(( u16_t *addr ));
struct nlist *nlist_p, *nlist_ptr;
int exec_fd;
struct exec exec_header;
#ifndef USE_OLD_NLIST
struct old_nlist *old_nlist, *old_nlist_p;
void *old_nlist_end;
#endif
char *str_tab, *str_base, *str_null;
u32_t string_siz;
exec_fd= open(filename, O_RDONLY);
if (exec_fd == -1) /* No executable present */
{
return -1;
}
r= read(exec_fd, (char *)&exec_header, A_MINHDR);
if (r != A_MINHDR)
{
if (r != -1)
errno= ENOEXEC;
return -1;
}
if (BADMAG(exec_header))
{
errno= ENOEXEC;
return -1;
}
switch(exec_header.a_cpu & 3)
{
case 0: /* little endian */
cnv32= le32;
cnv16= le16;
break;
case 3: /* big endian */
cnv32= be32;
cnv16= be16;
break;
default:
errno= ENOEXEC;
return -1;
}
exec_header.a_version= cnv16((u16_t *)&exec_header.a_version);
exec_header.a_text= cnv32((u32_t *)&exec_header.a_text);
exec_header.a_data= cnv32((u32_t *)&exec_header.a_data);
exec_header.a_bss= cnv32((u32_t *)&exec_header.a_bss);
exec_header.a_entry= cnv32((u32_t *)&exec_header.a_entry);
exec_header.a_total= cnv32((u32_t *)&exec_header.a_total);
exec_header.a_syms= cnv32((u32_t *)&exec_header.a_syms);
exec_header.a_trsize= cnv32((u32_t *)&exec_header.a_trsize);
exec_header.a_drsize= cnv32((u32_t *)&exec_header.a_drsize);
exec_header.a_tbase= cnv32((u32_t *)&exec_header.a_tbase);
exec_header.a_dbase= cnv32((u32_t *)&exec_header.a_dbase);
if (!exec_header.a_syms)
return 0;
if (exec_header.a_flags & A_NSYM)
{
#if USE_OLD_NLIST
errno= EINVAL;
return -1;
#else
r= lseek(exec_fd, A_SYMPOS(exec_header)+exec_header.a_syms,
SEEK_SET);
if (r == -1)
{
return -1;
}
r= read(exec_fd, (char *)&string_siz, 4);
if (r != 4)
return -1;
string_siz= cnv32(&string_siz)-4;
nlist_p= malloc(exec_header.a_syms + string_siz+1);
if (!nlist_p)
{
errno= ENOMEM;
return -1;
}
r= lseek(exec_fd, A_SYMPOS(exec_header)+exec_header.a_syms+4,
SEEK_SET);
if (r == -1)
{
save_err= errno;
free(nlist_p);
errno= save_err;
return -1;
}
r= read(exec_fd, ((char *)nlist_p)+exec_header.a_syms,
string_siz);
if (r != string_siz)
{
save_err= errno;
free(nlist_p);
errno= save_err;
return -1;
}
r= lseek(exec_fd, A_SYMPOS(exec_header), SEEK_SET);
if (r == -1)
{
save_err= errno;
free(nlist_p);
errno= save_err;
return -1;
}
r= read(exec_fd, ((char *)nlist_p), exec_header.a_syms);
if (r != exec_header.a_syms)
{
save_err= errno;
free(nlist_p);
errno= save_err;
return -1;
}
str_base= ((char *)nlist_p) + exec_header.a_syms -4;
str_null= (char *)nlist_p + exec_header.a_syms + string_siz;
*str_null= '\0';
for (nlist_ptr= nlist_p; (char *)nlist_ptr+1 <= str_base+4;
nlist_ptr++)
{
nlist_ptr->n_desc= le16((u16_t *)&nlist_ptr->n_desc);
nlist_ptr->n_value= le32(&nlist_ptr->n_value);
if (nlist_ptr->n_un.n_strx)
nlist_ptr->n_un.n_name= str_base+
cnv32((u32_t *)&nlist_ptr->n_un.n_strx);
else
nlist_ptr->n_un.n_name= str_null;
}
*nlist_table= nlist_p;
return nlist_ptr-nlist_p;
#endif
}
else
{
r= lseek(exec_fd, A_SYMPOS(exec_header), SEEK_SET);
if (r == -1)
{
return -1;
}
#if USE_OLD_NLIST
n_entries= exec_header.a_syms/sizeof(struct nlist);
nlist_p= malloc(exec_header.a_syms);
if (!nlist_p)
{
free(nlist_p);
errno= ENOMEM;
return -1;
}
r= read(exec_fd, (char *)nlist_p, exec_header.a_syms);
if (r != exec_header.a_syms)
{
save_err= errno;
free(nlist_p);
errno= save_err;
return -1;
}
*nlist_table= nlist_p;
return n_entries;
#else
n_entries= exec_header.a_syms/sizeof(struct old_nlist)+1;
nlist_p= NULL;
old_nlist= NULL;
nlist_p= malloc(n_entries * (sizeof(struct nlist)+
sizeof(old_nlist->n_name)+1));
old_nlist= malloc(exec_header.a_syms);
if (!old_nlist || !nlist_p)
{
if (nlist_p)
free(nlist_p);
if (old_nlist)
free(old_nlist);
errno= ENOMEM;
return -1;
}
r= read(exec_fd, (char *)old_nlist, exec_header.a_syms);
if (r != exec_header.a_syms)
{
save_err= errno;
free(nlist_p);
free(old_nlist);
errno= save_err;
return -1;
}
old_nlist_end= (char *)old_nlist+exec_header.a_syms;
str_tab= (char *)&nlist_p[n_entries];
n_entries= 0;
for (old_nlist_p= old_nlist;
(void *)(old_nlist_p+1)<=old_nlist_end; old_nlist_p++)
{
switch(old_nlist_p->n_sclass & O_N_SECT)
{
case O_N_UNDF:
nlist_p[n_entries].n_type= N_UNDF;
break;
case O_N_ABS:
nlist_p[n_entries].n_type= N_ABS;
break;
case O_N_TEXT:
nlist_p[n_entries].n_type= N_TEXT;
break;
case O_N_DATA:
nlist_p[n_entries].n_type= N_DATA;
break;
case O_N_BSS:
nlist_p[n_entries].n_type= N_BSS;
break;
case O_N_COMM:
nlist_p[n_entries].n_type= N_COMM;
break;
default:
continue;
}
switch(old_nlist_p->n_sclass & O_N_CLASS)
{
case O_C_EXT:
nlist_p[n_entries].n_type |= N_EXT;
case O_C_STAT:
break;
default:
continue;
}
nlist_p[n_entries].n_value=
cnv32((u32_t *)&old_nlist_p->n_value);
nlist_p[n_entries].n_un.n_name= str_tab;
memcpy(str_tab, old_nlist_p->n_name,
sizeof(old_nlist_p->n_name));
str_tab += sizeof(old_nlist_p->n_name);
*str_tab++= '\0';
n_entries++;
}
free(old_nlist);
nlist_p= realloc(nlist_p, str_tab-(char *)nlist_p);
*nlist_table= nlist_p;
return n_entries;
#endif
}
}
/*
* $PchId: read_nlist.c,v 1.5 1996/04/11 07:47:38 philip Exp $
*/

99
commands/swifi/rnd.c Normal file
View file

@ -0,0 +1,99 @@
/*
rnd.c
Generate random numbers
*/
#define _POSIX_SOURCE
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static char *progname;
static void fatal(char *fmt, ...);
static void usage(void);
int main(int argc, char *argv[])
{
int c, i, count;
unsigned long n, v, high, modulus;
unsigned seed;
char *check;
char *c_arg, *m_arg, *s_arg;
(progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
c_arg= m_arg= s_arg= NULL;
while (c= getopt(argc, argv, "?c:m:s:"), c != -1)
{
switch(c)
{
case 'c': c_arg= optarg; break;
case 'm': m_arg= optarg; break;
case 's': s_arg= optarg; break;
default:
fatal("getopt failed: '%c'", c);
}
}
if (optind != argc)
usage();
if (c_arg)
{
count= strtol(c_arg, &check, 0);
if (check[0] != '\0')
fatal("bad count '%s'", c_arg);
}
else
count= 1;
if (m_arg)
{
modulus= strtoul(m_arg, &check, 0);
if (check[0] != '\0' || modulus == 0)
fatal("bad modulus '%s'", m_arg);
n= 0x80000000UL / modulus;
if (n == 0)
fatal("bad modulus %lu (too big)", modulus);
high= n * modulus;
}
else
modulus= high= 0x80000000UL;
if (s_arg)
{
seed= strtol(s_arg, &check, 0);
if (check[0] != '\0')
fatal("bad seed '%s'", s_arg);
srandom(seed);
}
for (i= 0; i<count; i++)
{
do
{
v= random();
} while (v > high);
printf("%lu\n", v % modulus);
}
}
static void fatal(char *fmt, ...)
{
va_list ap;
fprintf(stderr, "%s: ", progname);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(1);
}
static void usage(void)
{
fprintf(stderr, "Usage: rnd [-c <count>] [-m <modulus>] [-s <seed>]\n");
exit(1);
}

5
commands/swifi/rs.restart_imm Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
# 'Recovery' script immediately restarts.
echo "Arguments: $@" >/dev/console
service restart "$1"

58
commands/swifi/run_swifi Normal file
View file

@ -0,0 +1,58 @@
#!/bin/sh
LABEL=dp8390
EXEDIR=/usr/build/drivers/dp8390
EXE=$EXEDIR/$LABEL
:>log
do_one()
{
# $1 = test-nr, $2 = count, $3 = seed
pid=''
while [ X"$pid" = X ]
do
pid=`ps ax | grep $LABEL | grep -v grep |
sed 's,^[ ]*,,;s,[ ].*,,`
if [ X"$pid" != X ]
then
break
fi
sleep 10
done
echo pid = $pid
./swifi -f $EXE $pid $1 $2 $3 >/tmp/out
sleep 1
kill -0 $pid &&
echo "driver failed to die, params: test $1, count $2, seed $3"
}
one_round()
{
# $1 = count, $2 = seed
count=$1
seed=$2
echo "Seed: $seed" >> log
sync
do_one 6 $count $seed # Source fault
do_one 5 $count $seed # Destination fault
do_one 8 $count $seed # Pointer fault
do_one 14 $count $seed # Interface fault
do_one 12 $count $seed # Loop fault
do_one 0 $count $seed # Text fault
do_one 4 $count $seed # Nop fault
}
# Start our own driver.
service down $LABEL
sleep 10 # Allow driver to die
service up $EXE -script `pwd`/rs.restart_imm -config /etc/drivers.conf -period 3HZ
i=0
i=4000
while [ $i -lt 10000 ]
do
echo "Seed: $i"
one_round 100 $i
i=`expr $i + 1`
done

View file

@ -0,0 +1,39 @@
#!/bin/sh
do_one()
{
# $1 = test-nr, $2 = count, $3 = seed
pid=''
while [ X"$pid" = X ]
do
pid=`ps ax | grep dp8390 | grep usr.sbin |
sed 's,^[ ]*,,;s,[ ].*,,`
sleep 1
done
echo pid = $pid
./swifi -f /usr/build/drivers/dp8390/dp8390 $pid $1 $2 $3 >/tmp/out
sleep 5
kill -0 $pid &&
echo "driver failed to die, params: test $1, count $2, seed $3"
}
one_round()
{
# $1 = count, $2 = seed
count=$1
seed=$2
do_one 6 $count $seed # Source fault
do_one 5 $count $seed # Destination fault
do_one 8 $count $seed # Pointer fault
do_one 14 $count $seed # Interface fault
do_one 12 $count $seed # Loop fault
do_one 0 $count $seed # Text fault
do_one 4 $count $seed # Nop fault
}
i=4
while [ $i -lt 100 ]
do
echo "Seed: $i"
one_round 100 $i
i=`expr $i + 1`
done

122
commands/swifi/run_t1 Executable file
View file

@ -0,0 +1,122 @@
#!/bin/sh
LABEL=es1371
EXEDIR=/usr/build/drivers/es1371
#LABEL=fxp
#EXEDIR=/usr/build/drivers/fxp
EXE=$EXEDIR/$LABEL
DEV="-dev /dev/audio"
:>log
do_one()
{
# $1 = test-nr, $2 = count, $3 = seed
pid=''
while [ X"$pid" = X ]
do
ps ax | grep $LABEL | grep -v grep
pid=`ps ax | grep $LABEL | grep -v grep |
sort -n | tail -1 |
sed 's,^[ ]*,,;s,[ ].*,,`
if [ X"$pid" != X ]
then
break
fi
sleep 10
done
echo pid = $pid
./swifi -f $EXE $pid $1 $2 $3 >/tmp/out
sleep 1
kill -0 $pid &&
echo "driver failed to die, params: test $1, count $2, seed $3"
}
one_round()
{
# $1 = count, $2 = seed
count=$1
seed=$2
echo "Seed: $seed" >> log
sync
do_one 6 $count $seed # Source fault
do_one 5 $count $seed # Destination fault
do_one 8 $count $seed # Pointer fault
do_one 14 $count $seed # Interface fault
do_one 12 $count $seed # Loop fault
do_one 0 $count $seed # Text fault
do_one 4 $count $seed # Nop fault
}
usage()
{
echo "Usage: run_t1 <count> <type> <seed>" >&2
echo \
"Valid types are: source destination pointer interface loop text nop random" >&2
exit 1
}
select_from()
{
# $1 = index, $2... = choices
index="$1"
index=`expr "$index" + 1`
shift
v=`eval echo '$'$index`
echo "$v"
}
random_type()
{
# $1 = seed
seed="$1"
r=`./rnd -m 7 -s "$seed"`
select_from "$r" 6 5 8 14 12 0 4
}
if [ $# -ne 3 ]; then usage; fi
count="$1"
type="$2"
seed="$3"
case "$type" in
source) type_arg=6
;;
destination) type_arg=5
;;
pointer) type_arg=8
;;
interface) type_arg=14
;;
loop) type_arg=12
;;
text) type_arg=0
;;
nop) type_arg=4
;;
random)
;;
*)
usage
esac
# Start our own driver.
service down $LABEL
sleep 2 # Allow driver to die
service -i up $EXE -script `pwd`/rs.restart_imm -config /etc/drivers.conf -period 3HZ $DEV
i=0
while [ $i -lt "$count" ]
do
echo "Seed: $seed"
if [ "$type" = "random" ]
then
type_arg=`random_type $seed`
fi
do_one "$type_arg" 100 $seed
i=`expr $i + 1`
seed=`expr $seed + 1`
done
# Restart the driver
service refresh $LABEL

23
commands/swifi/run_t1a Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh
set -x
if [ $# -ne 2 ]; then usage; fi
type="$1"
run="$2"
count=1000
# Rotate syslog
LOGFILE=/var/log/messages
mv $LOGFILE $LOGFILE.prev
(cd /var/log && : > messages)
kill -1 `ps ax | grep syslogd | grep -v grep |
sed 's,^[ ]*,,;s,[ ].*,,'`
./run_t1 $count $type `expr $run \* 1000` 2>&1 |
tee results/1.$type.$run.out
cp $LOGFILE results/1.$type.$run.log

14
commands/swifi/run_t1b Executable file
View file

@ -0,0 +1,14 @@
#!/bin/sh
run=0
./run_t1a interface $run
./run_t1a source $run
./run_t1a destination $run
./run_t1a pointer $run
./run_t1a interface $run
./run_t1a loop $run
./run_t1a text $run
./run_t1a nop $run
./run_t1a random $run

146
commands/swifi/run_t2 Executable file
View file

@ -0,0 +1,146 @@
#!/bin/sh
LABEL=dp8390
EXEDIR=/usr/build/drivers/dp8390
EXE=$EXEDIR/$LABEL
DAYTIME_HOST=jetsam.cs.vu.nl
FAULTS_PER_BLOCK=1
:>log
fault_blocks=0
connect_blocks=0
dont_connect=0
do_one()
{
# $1 = test-nr, $2 = count, $3 = seed
pid=''
while [ X"$pid" = X ]
do
pid=`ps ax | grep $LABEL | grep -v grep |
sed 's,^[ ]*,,;s,[ ].*,,`
if [ X"$pid" != X ]
then
break
fi
sleep 10
done
echo pid = $pid
./swifi -f $EXE $pid $1 $2 $3 >/tmp/out
sleep 1
fault_blocks=`expr $fault_blocks + 1`
if kill -0 $pid
then
if [ $dont_connect -eq 0 ]
then
if ./socket -t 10 $DAYTIME_HOST daytime < /dev/null
then
connect_blocks=`expr $connect_blocks + 1`
else
dont_connect=1
fi
fi
echo "driver failed to die, params: test $1, count $2, seed $3"
else
connect_blocks=`expr $connect_blocks + 1`
echo "driver crashed after $fault_blocks blocks"
echo "driver failed to connect after $connect_blocks blocks"
fault_blocks=0
connect_blocks=0
dont_connect=0
fi
}
one_round()
{
# $1 = count, $2 = seed
count=$1
seed=$2
echo "Seed: $seed" >> log
sync
do_one 6 $count $seed # Source fault
do_one 5 $count $seed # Destination fault
do_one 8 $count $seed # Pointer fault
do_one 14 $count $seed # Interface fault
do_one 12 $count $seed # Loop fault
do_one 0 $count $seed # Text fault
do_one 4 $count $seed # Nop fault
}
usage()
{
echo "Usage: run_t2 <count> <type> <seed>" >&2
echo \
"Valid types are: source destination pointer interface loop text nop random" >&2
exit 1
}
select_from()
{
# $1 = index, $2... = choices
index="$1"
index=`expr "$index" + 1`
shift
v=`eval echo '$'$index`
echo "$v"
}
random_type()
{
# $1 = seed
seed="$1"
r=`./rnd -m 7 -s "$seed"`
select_from "$r" 6 5 8 14 12 0 4
}
if [ $# -ne 3 ]; then usage; fi
count="$1"
type="$2"
seed="$3"
case "$type" in
source) type_arg=6
;;
destination) type_arg=5
;;
pointer) type_arg=8
;;
interface) type_arg=14
;;
loop) type_arg=12
;;
text) type_arg=0
;;
nop) type_arg=4
;;
random)
;;
*)
usage
esac
# Start our own driver.
service down $LABEL
sleep 10 # Allow driver to die
service up $EXE -script `pwd`/rs.restart_imm -config /etc/drivers.conf -period 3HZ
i=0
while [ $i -lt "$count" ]
do
echo "Seed: $seed"
if [ "$type" = "random" ]
then
type_arg=`random_type $seed`
fi
do_one "$type_arg" $FAULTS_PER_BLOCK $seed
i=`expr $i + 1`
seed=`expr $seed + 1`
done
connect_blocks=`expr $connect_blocks + 1`
echo "driver crashed after $fault_blocks blocks"
echo "driver failed to connect after $connect_blocks blocks"
# Restart the driver
service refresh $LABEL

23
commands/swifi/run_t2a Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh
set -x
if [ $# -ne 2 ]; then usage; fi
type="$1"
run="$2"
count=10000
# Rotate syslog
LOGFILE=/var/log/messages
mv $LOGFILE $LOGFILE.prev
(cd /var/log && : > messages)
kill -1 `ps ax | grep syslogd | grep -v grep |
sed 's,^[ ]*,,;s,[ ].*,,'`
./run_t2 $count $type `expr $run \* 1000` 2>&1 |
tee results/2.$type.$run.out
cp $LOGFILE results/2.$type.$run.log

15
commands/swifi/run_t2b Executable file
View file

@ -0,0 +1,15 @@
#!/bin/sh
run=0
./run_t2a interface $run
exit
./run_t2a source $run
./run_t2a destination $run
./run_t2a pointer $run
#./run_t2a interface $run
./run_t2a loop $run
#./run_t2a text $run
#./run_t2a nop $run
#./run_t2a random $run

306
commands/swifi/socket.c Normal file
View file

@ -0,0 +1,306 @@
/*
socket.c
Created: Feb 2001 by Philip Homburg <philip@f-mnx.phicoh.com>
Open a TCP connection
*/
#define _POSIX_C_SOURCE 2
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <net/hton.h>
#include <net/netlib.h>
#include <net/gen/in.h>
#include <net/gen/inet.h>
#include <net/gen/netdb.h>
#include <net/gen/socket.h>
#include <net/gen/tcp.h>
#include <net/gen/tcp_io.h>
#define BUF_SIZE 10240
char *progname;
int tcpfd= -1;
char buf[BUF_SIZE];
static int bulk= 0;
static int push= 0;
static int stdout_issocket= 0;
static int timeout;
static void do_conn(char *hostname, char *portname);
static void alrm_conn(int sig);
static void alrm_io(int sig);
static void fullduplex(void);
static void fatal(char *msg, ...);
static void usage(void);
int main(int argc, char *argv[])
{
int c;
char *hostname;
char *portname;
char *check;
int B_flag, P_flag, s_flag;
char *t_arg;
(progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
B_flag= 0;
P_flag= 0;
s_flag= 0;
t_arg= NULL;
while (c= getopt(argc, argv, "BPst:?"), c != -1)
{
switch(c)
{
case 'B': B_flag= 1; break;
case 'P': P_flag= 1; break;
case 's': s_flag= 1; break;
case 't': t_arg= optarg; break;
case '?': usage();
default:
fatal("getopt failed: '%c'", c);
}
}
if (t_arg)
{
timeout= strtol(t_arg, &check, 0);
if (check[0] != '\0')
fatal("unable to parse timeout '%s'\n", t_arg);
if (timeout <= 0)
fatal("bad timeout '%d'\n", timeout);
}
else
timeout= 0;
if (optind+2 != argc)
usage();
hostname= argv[optind++];
portname= argv[optind++];
bulk= B_flag;
push= P_flag;
stdout_issocket= s_flag;
do_conn(hostname, portname);
/* XXX */
if (timeout)
{
signal(SIGALRM, alrm_io);
alarm(timeout);
}
fullduplex();
exit(0);
}
static void do_conn(char *hostname, char *portname)
{
ipaddr_t addr;
tcpport_t port;
struct hostent *he;
struct servent *se;
char *tcp_device, *check;
nwio_tcpconf_t tcpconf;
nwio_tcpcl_t tcpcl;
nwio_tcpopt_t tcpopt;
if (!inet_aton(hostname, &addr))
{
he= gethostbyname(hostname);
if (he == NULL)
fatal("unknown hostname '%s'", hostname);
if (he->h_addrtype != AF_INET || he->h_length != sizeof(addr))
fatal("bad address for '%s'", hostname);
memcpy(&addr, he->h_addr, sizeof(addr));
}
port= strtol(portname, &check, 0);
if (check[0] != 0)
{
se= getservbyname(portname, "tcp");
if (se == NULL)
fatal("unkown port '%s'", portname);
port= ntohs(se->s_port);
}
tcp_device= getenv("TCP_DEVICE");
if (tcp_device == NULL) tcp_device= TCP_DEVICE;
tcpfd= open(tcp_device, O_RDWR);
if (tcpfd == -1)
fatal("unable to open '%s': %s", tcp_device, strerror(errno));
tcpconf.nwtc_flags= NWTC_EXCL | NWTC_LP_SEL | NWTC_SET_RA |
NWTC_SET_RP;
tcpconf.nwtc_remaddr= addr;
tcpconf.nwtc_remport= htons(port);;
if (ioctl(tcpfd, NWIOSTCPCONF, &tcpconf) == -1)
fatal("NWIOSTCPCONF failed: %s", strerror(errno));
if (timeout)
{
signal(SIGALRM, alrm_conn);
alarm(timeout);
}
tcpcl.nwtcl_flags= 0;
if (ioctl(tcpfd, NWIOTCPCONN, &tcpcl) == -1)
{
fatal("unable to connect to %s:%u: %s", inet_ntoa(addr),
ntohs(tcpconf.nwtc_remport), strerror(errno));
}
alarm(0);
if (bulk)
{
tcpopt.nwto_flags= NWTO_BULK;
if (ioctl(tcpfd, NWIOSTCPOPT, &tcpopt) == -1)
fatal("NWIOSTCPOPT failed: %s", strerror(errno));
}
}
static void alrm_conn(int sig)
{
fatal("timeout during connect");
}
static void alrm_io(int sig)
{
fatal("timeout during io");
}
static void fullduplex(void)
{
pid_t cpid;
int o, r, s, s_errno, loc;
cpid= fork();
switch(cpid)
{
case -1: fatal("fork failed: %s", strerror(errno));
case 0:
/* Read from TCP, write to stdout. */
for (;;)
{
r= read(tcpfd, buf, BUF_SIZE);
if (r == 0)
break;
if (r == -1)
{
r= errno;
if (stdout_issocket)
ioctl(1, NWIOTCPSHUTDOWN, NULL);
fatal("error reading from TCP conn.: %s",
strerror(errno));
}
s= r;
for (o= 0; o<s; o += r)
{
r= write(1, buf+o, s-o);
if (r <= 0)
{
fatal("error writing to stdout: %s",
r == 0 ? "EOF" :
strerror(errno));
}
}
}
if (stdout_issocket)
{
r= ioctl(1, NWIOTCPSHUTDOWN, NULL);
if (r == -1)
{
fatal("NWIOTCPSHUTDOWN failed on stdout: %s",
strerror(errno));
}
}
exit(0);
default:
break;
}
/* Read from stdin, write to TCP. */
for (;;)
{
r= read(0, buf, BUF_SIZE);
if (r == 0)
break;
if (r == -1)
{
s_errno= errno;
kill(cpid, SIGTERM);
fatal("error reading from stdin: %s",
strerror(s_errno));
}
s= r;
for (o= 0; o<s; o += r)
{
r= write(tcpfd, buf+o, s-o);
if (r <= 0)
{
s_errno= errno;
kill(cpid, SIGTERM);
fatal("error writing to TCP conn.: %s",
r == 0 ? "EOF" :
strerror(s_errno));
}
}
if (push)
ioctl(tcpfd, NWIOTCPPUSH, NULL);
}
if (ioctl(tcpfd, NWIOTCPSHUTDOWN, NULL) == -1)
{
s_errno= errno;
kill(cpid, SIGTERM);
fatal("unable to shut down TCP conn.: %s", strerror(s_errno));
}
r= waitpid(cpid, &loc, 0);
if (r == -1)
{
s_errno= errno;
kill(cpid, SIGTERM);
fatal("waitpid failed: %s", strerror(s_errno));
}
if (WIFEXITED(loc))
exit(WEXITSTATUS(loc));
kill(getpid(), WTERMSIG(loc));
exit(1);
}
static void fatal(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(1);
}
static void usage(void)
{
fprintf(stderr, "Usage: %s [-BPs] [-t timeout] hostname portname\n",
progname);
exit(1);
}
/*
* $PchId: socket.c,v 1.3 2005/01/31 22:33:20 philip Exp $
*/

123
commands/swifi/systest.c Normal file
View file

@ -0,0 +1,123 @@
/*
* systest.c -- Test code for nooks system calls
*
* Copyright (C) 2002 Mike Swift
*
* The source code in this file can be freely used, adapted,
* and redistributed in source or binary form, so long as an
* acknowledgment appears in derived source files.
* No warranty is attached;
* we cannot take responsibility for errors or fitness for use.
*
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#if 0
#include <asm/unistd.h>
#endif
#include <string.h>
#include <errno.h>
#define swifi_inject_fault sys_inject_fault
#include "swifi-user.h"
#include "extra.h"
#if 0
_syscall6(long, swifi_inject_fault,
char *, module_name,
unsigned long, faultType,
unsigned long, randSeed,
unsigned long, numFaults,
void *, result,
unsigned long, do_inject);
#endif
int
main(int argc, char * argv[])
{
char * module_name = NULL;
int i;
long result = 0;
unsigned int cmd = 0;
unsigned long arg = 0;
unsigned long seed = 157;
swifi_result_t * res = NULL;
if (argc < 2) {
goto Usage;
}
for (i = 1; i < argc; i++ ) {
if (strcmp(argv[i], "-f") == 0) {
if (argc <= i+5) {
goto Usage;
}
module_name = victim_exe = argv[++i];
sscanf(argv[++i],"%u", &victim_pid);
sscanf(argv[++i],"%u", &cmd);
sscanf(argv[++i],"%lu", &arg);
sscanf(argv[++i],"%lu", &seed);
} else {
printf("Unknown command %s\n", argv[i]);
goto Usage;
}
}
res = malloc(arg * sizeof(swifi_result_t));
if (res == NULL) {
printf("Out of memory\n");
goto Cleanup;
}
memset(res, 0, sizeof(res));
/*
// Find out where the faults will be injected
*/
result = swifi_inject_fault(module_name,
cmd, /* fault type */
seed, /* random seed */
arg, /* numFaults */
res,
0); /* don't inject now */
for (i = 0; (i < arg) && (res[i].address != 0) ; i++) {
printf("Changed 0x%lx from 0x%lx to 0x%lx\n",
res[i].address,
res[i].old,
res[i].new);
}
/*
// do the injection
*/
result = swifi_inject_fault(module_name,
cmd, /* fault type */
seed, /* random seed */
arg, /* numFaults */
res,
1); /* do inject now */
printf("swifi_inject_fault returned %ld (%d)\n", result,errno);
Cleanup:
if (res != NULL) {
free(res);
}
return(0);
Usage:
printf("Usage: %s -f module_name pid fault-type fault-count seed\n", argv[0]);
goto Cleanup;
}