Minix 3 version
This commit is contained in:
parent
659ab96c1f
commit
5b5b54c76c
19 changed files with 1830 additions and 118 deletions
|
@ -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
4
commands/swifi/do_swifi
Normal 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
|
4
commands/swifi/do_swifi_bug1
Normal file
4
commands/swifi/do_swifi_bug1
Normal 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
250
commands/swifi/extra.c
Normal 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
96
commands/swifi/extra.h
Normal 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);
|
|
@ -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
329
commands/swifi/read_nlist.c
Normal 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
99
commands/swifi/rnd.c
Normal 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
5
commands/swifi/rs.restart_imm
Executable 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
58
commands/swifi/run_swifi
Normal 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
|
39
commands/swifi/run_swifi-x
Normal file
39
commands/swifi/run_swifi-x
Normal 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
122
commands/swifi/run_t1
Executable 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
23
commands/swifi/run_t1a
Executable 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
14
commands/swifi/run_t1b
Executable 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
146
commands/swifi/run_t2
Executable 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
23
commands/swifi/run_t2a
Executable 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
15
commands/swifi/run_t2b
Executable 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
306
commands/swifi/socket.c
Normal 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
123
commands/swifi/systest.c
Normal 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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue