mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-24 03:49:45 +00:00
executor: add support for 386 arch (COMPAT syscalls)
This is not fully working now: e.g. prog and sys packages assume that pointer size is 8. But at least it compiles and works.
This commit is contained in:
parent
2ce72987a6
commit
32061a606f
@ -34,8 +34,8 @@
|
||||
|
||||
#include "syscalls.h"
|
||||
|
||||
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
|
||||
#define KCOV_INIT_TABLE _IOR('c', 2, unsigned long)
|
||||
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long long)
|
||||
#define KCOV_INIT_TABLE _IOR('c', 2, unsigned long long)
|
||||
#define KCOV_ENABLE _IO('c', 100)
|
||||
#define KCOV_DISABLE _IO('c', 101)
|
||||
|
||||
@ -94,7 +94,7 @@ struct thread_t {
|
||||
bool created;
|
||||
int id;
|
||||
pthread_t th;
|
||||
uintptr_t* cover_data;
|
||||
uint64_t* cover_data;
|
||||
uint64_t* copyout_pos;
|
||||
int ready;
|
||||
int done;
|
||||
@ -103,10 +103,10 @@ struct thread_t {
|
||||
int call_index;
|
||||
int call_num;
|
||||
int num_args;
|
||||
uint64_t args[kMaxArgs];
|
||||
uintptr_t args[kMaxArgs];
|
||||
uint64_t res;
|
||||
uint64_t reserrno;
|
||||
uintptr_t cover_size;
|
||||
uint64_t cover_size;
|
||||
int cover_fd;
|
||||
};
|
||||
|
||||
@ -137,8 +137,8 @@ uint64_t current_time_ms();
|
||||
void cover_open();
|
||||
void cover_enable(thread_t* th);
|
||||
void cover_reset(thread_t* th);
|
||||
uintptr_t cover_read(thread_t* th);
|
||||
uintptr_t cover_dedup(thread_t* th, uintptr_t n);
|
||||
uint64_t cover_read(thread_t* th);
|
||||
uint64_t cover_dedup(thread_t* th, uint64_t n);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
@ -540,7 +540,7 @@ void handle_completion(thread_t* th)
|
||||
write_output(th->cover_size);
|
||||
// Truncate PCs to uint32_t assuming that they fit into 32-bits.
|
||||
// True for x86_64 and arm64 without KASLR.
|
||||
for (uint32_t i = 0; i < th->cover_size; i++)
|
||||
for (uint64_t i = 0; i < th->cover_size; i++)
|
||||
write_output((uint32_t)th->cover_data[i + 1]);
|
||||
completed++;
|
||||
__atomic_store_n((uint32_t*)&output_data[0], completed, __ATOMIC_RELEASE);
|
||||
@ -651,9 +651,9 @@ void execute_call(thread_t* th)
|
||||
int fd = open("/dev/fuse", O_RDWR);
|
||||
if (fd != -1) {
|
||||
char buf[256];
|
||||
sprintf(buf, "fd=%d,user_id=%lu,group_id=%lu,rootmode=0%o", fd, uid, gid, (unsigned)mode & ~3u);
|
||||
sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd, (long)uid, (long)gid, (unsigned)mode & ~3u);
|
||||
if (maxread != 0)
|
||||
sprintf(buf + strlen(buf), ",max_read=%lu", maxread);
|
||||
sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
|
||||
if (mode & 1)
|
||||
strcat(buf, ",default_permissions");
|
||||
if (mode & 2)
|
||||
@ -679,11 +679,11 @@ void execute_call(thread_t* th)
|
||||
if (fd != -1) {
|
||||
if (syscall(SYS_mknodat, AT_FDCWD, blkdev, S_IFBLK, makedev(7, 199)) == 0) {
|
||||
char buf[256];
|
||||
sprintf(buf, "fd=%d,user_id=%lu,group_id=%lu,rootmode=0%o", fd, uid, gid, (unsigned)mode & ~3u);
|
||||
sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd, (long)uid, (long)gid, (unsigned)mode & ~3u);
|
||||
if (maxread != 0)
|
||||
sprintf(buf + strlen(buf), ",max_read=%lu", maxread);
|
||||
sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
|
||||
if (blksize != 0)
|
||||
sprintf(buf + strlen(buf), ",blksize=%lu", blksize);
|
||||
sprintf(buf + strlen(buf), ",blksize=%ld", (long)blksize);
|
||||
if (mode & 1)
|
||||
strcat(buf, ",default_permissions");
|
||||
if (mode & 2)
|
||||
@ -717,8 +717,8 @@ void cover_open()
|
||||
if (th->cover_fd == -1)
|
||||
fail("open of /sys/kernel/debug/kcov failed");
|
||||
if (ioctl(th->cover_fd, KCOV_INIT_TRACE, kCoverSize))
|
||||
fail("cover enable write failed");
|
||||
th->cover_data = (uintptr_t*)mmap(NULL, kCoverSize * sizeof(th->cover_data[0]), PROT_READ | PROT_WRITE, MAP_SHARED, th->cover_fd, 0);
|
||||
fail("cover init write failed");
|
||||
th->cover_data = (uint64_t*)mmap(NULL, kCoverSize * sizeof(th->cover_data[0]), PROT_READ | PROT_WRITE, MAP_SHARED, th->cover_fd, 0);
|
||||
if ((void*)th->cover_data == MAP_FAILED)
|
||||
fail("cover mmap failed");
|
||||
}
|
||||
@ -741,11 +741,11 @@ void cover_reset(thread_t* th)
|
||||
__atomic_store_n(&th->cover_data[0], 0, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
uintptr_t cover_read(thread_t* th)
|
||||
uint64_t cover_read(thread_t* th)
|
||||
{
|
||||
if (!flag_cover)
|
||||
return 0;
|
||||
uintptr_t n = __atomic_load_n(&th->cover_data[0], __ATOMIC_RELAXED);
|
||||
uint64_t n = __atomic_load_n(&th->cover_data[0], __ATOMIC_RELAXED);
|
||||
debug("#%d: read cover = %d\n", th->id, n);
|
||||
if (n >= kCoverSize)
|
||||
fail("#%d: too much cover %d", th->id, n);
|
||||
@ -756,14 +756,14 @@ uintptr_t cover_read(thread_t* th)
|
||||
return n;
|
||||
}
|
||||
|
||||
uintptr_t cover_dedup(thread_t* th, uintptr_t n)
|
||||
uint64_t cover_dedup(thread_t* th, uint64_t n)
|
||||
{
|
||||
uintptr_t* cover_data = th->cover_data + 1;
|
||||
uint64_t* cover_data = th->cover_data + 1;
|
||||
std::sort(cover_data, cover_data + n);
|
||||
uintptr_t w = 0;
|
||||
uintptr_t last = 0;
|
||||
for (uintptr_t i = 0; i < n; i++) {
|
||||
uintptr_t pc = cover_data[i];
|
||||
uint64_t w = 0;
|
||||
uint64_t last = 0;
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
uint64_t pc = cover_data[i];
|
||||
if (pc == last)
|
||||
continue;
|
||||
cover_data[w++] = last = pc;
|
||||
|
1113
executor/syscalls.h
1113
executor/syscalls.h
File diff suppressed because it is too large
Load Diff
8
sys/sys_386.go
Normal file
8
sys/sys_386.go
Normal file
File diff suppressed because one or more lines are too long
@ -15,7 +15,7 @@ import (
|
||||
// fetchValues converts literal constants (e.g. O_APPEND) or any other C expressions
|
||||
// into their respective numeric values. It does so by builting and executing a C program
|
||||
// that prints values of the provided expressions.
|
||||
func fetchValues(arch string, vals []string, includes []string, defines map[string]string) []string {
|
||||
func fetchValues(arch string, vals []string, includes []string, defines map[string]string, cflags []string) []string {
|
||||
logf(1, "Use C compiler to fetch constant values for arch=%v", arch)
|
||||
includeText := ""
|
||||
for _, inc := range includes {
|
||||
@ -37,6 +37,7 @@ func fetchValues(arch string, vals []string, includes []string, defines map[stri
|
||||
logf(2, " Build C program into temp file %v", bin.Name())
|
||||
|
||||
args := []string{"-x", "c", "-", "-o", bin.Name()}
|
||||
args = append(args, cflags...)
|
||||
args = append(args, []string{
|
||||
// This would be useful to ensure that we don't include any host headers,
|
||||
// but kernel includes at least <stdarg.h>
|
||||
|
@ -15,13 +15,15 @@ type Arch struct {
|
||||
CARCH []string
|
||||
KernelHeaderArch string
|
||||
KernelInclude string
|
||||
CFlags []string
|
||||
Numbers []int
|
||||
}
|
||||
|
||||
var archs = []*Arch{
|
||||
{"amd64", []string{"__x86_64__"}, "x86", "asm/unistd.h", nil},
|
||||
{"arm64", []string{"__aarch64__"}, "arm64", "asm/unistd.h", nil},
|
||||
{"ppc64le", []string{"__ppc64__", "__PPC64__", "__powerpc64__"}, "powerpc", "asm/unistd.h", nil},
|
||||
{"amd64", []string{"__x86_64__"}, "x86", "asm/unistd.h", []string{"-m64"}, nil},
|
||||
{"386", []string{"__i386__"}, "x86", "asm/unistd.h", []string{"-D__SYSCALL_COMPAT", "-DCONFIG_COMPAT", "-DCONFIG_X86_32"}, nil},
|
||||
{"arm64", []string{"__aarch64__"}, "arm64", "asm/unistd.h", []string{}, nil},
|
||||
{"ppc64le", []string{"__ppc64__", "__PPC64__", "__powerpc64__"}, "powerpc", "asm/unistd.h", []string{}, nil},
|
||||
}
|
||||
|
||||
var syzkalls = map[string]int{
|
||||
@ -51,7 +53,7 @@ func fetchSyscallsNumbers(arch *Arch, syscalls []Syscall) {
|
||||
defines[name] = strconv.Itoa(nr)
|
||||
}
|
||||
}
|
||||
for _, s := range fetchValues(arch.KernelHeaderArch, vals, includes, defines) {
|
||||
for _, s := range fetchValues(arch.KernelHeaderArch, vals, includes, defines, arch.CFlags) {
|
||||
n, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
failf("failed to parse syscall number '%v': %v", s, err)
|
||||
@ -61,7 +63,7 @@ func fetchSyscallsNumbers(arch *Arch, syscalls []Syscall) {
|
||||
}
|
||||
|
||||
func generateSyscallsNumbersArch(arch *Arch, syscalls []Syscall) {
|
||||
var archcode string = "sys/sys_"+arch.GOARCH+".go"
|
||||
var archcode string = "sys/sys_" + arch.GOARCH + ".go"
|
||||
logf(1, "Generate code with syscall numbers for arch=%v in %v", arch.GOARCH, archcode)
|
||||
buf := new(bytes.Buffer)
|
||||
if err := archTempl.Execute(buf, arch); err != nil {
|
||||
|
@ -18,9 +18,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
flagLinux = flag.String("linux", "", "path to linux kernel source checkout")
|
||||
flagLinux = flag.String("linux", "", "path to linux kernel source checkout")
|
||||
flagLinuxBld = flag.String("linuxbld", "", "path to linux kernel build directory")
|
||||
flagV = flag.Int("v", 0, "verbosity")
|
||||
flagV = flag.Int("v", 0, "verbosity")
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -569,7 +569,7 @@ func compileFlags(includes []string, defines map[string]string, flags map[string
|
||||
valArray = append(valArray, k)
|
||||
}
|
||||
// TODO: should use target arch
|
||||
flagVals := fetchValues("x86", valArray, includes, defines)
|
||||
flagVals := fetchValues("x86", valArray, includes, defines, []string{})
|
||||
for i, f := range valArray {
|
||||
vals[f] = flagVals[i]
|
||||
}
|
||||
@ -649,7 +649,7 @@ func parse(in io.Reader) (includes []string, defines map[string]string, syscalls
|
||||
} else {
|
||||
p.SkipWs()
|
||||
fld := []string{p.Ident()}
|
||||
logf(3, " Add field %f to struct %v", fld, str.Name)
|
||||
logf(3, " Add field %v to struct %v", fld, str.Name)
|
||||
fld = append(fld, parseType(p, unnamed, flags)...)
|
||||
str.Flds = append(str.Flds, fld)
|
||||
}
|
||||
@ -807,4 +807,3 @@ func logf(v int, msg string, args ...interface{}) {
|
||||
log.Printf(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user