diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-12-08 19:03:09 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-12-08 19:08:08 +0100 |
| commit | c7918378631992d874c99736272ed342d5d77b2c (patch) | |
| tree | 5e67097471fda876d532c270dc4b7f3db0e850c5 /pkg/csource | |
| parent | 33508266251f6db13ef34741e36b1dce2c9e1b49 (diff) | |
executor: fix handling of big-endian bitfields
Currently we apply big-endian-ness and bitfield-ness in the wrong order in copyin.
This leads to totally bogus result. Fix this.
Diffstat (limited to 'pkg/csource')
| -rw-r--r-- | pkg/csource/csource.go | 16 | ||||
| -rw-r--r-- | pkg/csource/generated.go | 27 |
2 files changed, 22 insertions, 21 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index 49431f655..aa5f615e1 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -229,7 +229,7 @@ func (ctx *context) emitCall(w *bytes.Buffer, call prog.ExecCall, ci int, haveCo if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian { panic("sring format in syscall argument") } - fmt.Fprintf(w, "%v", ctx.constArgToStr(arg)) + fmt.Fprintf(w, "%v", ctx.constArgToStr(arg, true)) case prog.ExecArgResult: if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian { panic("sring format in syscall argument") @@ -282,13 +282,17 @@ func (ctx *context) copyin(w *bytes.Buffer, csumSeq *int, copyin prog.ExecCopyin switch arg := copyin.Arg.(type) { case prog.ExecArgConst: if arg.BitfieldOffset == 0 && arg.BitfieldLength == 0 { - ctx.copyinVal(w, copyin.Addr, arg.Size, ctx.constArgToStr(arg), arg.Format) + ctx.copyinVal(w, copyin.Addr, arg.Size, ctx.constArgToStr(arg, true), arg.Format) } else { if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian { panic("bitfield+string format") } - fmt.Fprintf(w, "\tNONFAILING(STORE_BY_BITMASK(uint%v, 0x%x, %v, %v, %v));\n", - arg.Size*8, copyin.Addr, ctx.constArgToStr(arg), + htobe := "" + if arg.Format == prog.FormatBigEndian { + htobe = fmt.Sprintf("htobe%v", arg.Size*8) + } + fmt.Fprintf(w, "\tNONFAILING(STORE_BY_BITMASK(uint%v, %v, 0x%x, %v, %v, %v));\n", + arg.Size*8, htobe, copyin.Addr, ctx.constArgToStr(arg, false), arg.BitfieldOffset, arg.BitfieldLength) } case prog.ExecArgResult: @@ -363,7 +367,7 @@ func (ctx *context) copyout(w *bytes.Buffer, call prog.ExecCall, resCopyout bool } } -func (ctx *context) constArgToStr(arg prog.ExecArgConst) string { +func (ctx *context) constArgToStr(arg prog.ExecArgConst, handleBigEndian bool) string { mask := (uint64(1) << (arg.Size * 8)) - 1 v := arg.Value & mask val := fmt.Sprintf("%v", v) @@ -375,7 +379,7 @@ func (ctx *context) constArgToStr(arg prog.ExecArgConst) string { if ctx.opts.Procs > 1 && arg.PidStride != 0 { val += fmt.Sprintf(" + procid*%v", arg.PidStride) } - if arg.Format == prog.FormatBigEndian { + if handleBigEndian && arg.Format == prog.FormatBigEndian { val = fmt.Sprintf("htobe%v(%v)", arg.Size*8, val) } return val diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index a7bfe74d0..0c3ecb4e8 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -310,19 +310,10 @@ static int event_timedwait(event_t* ev, uint64 timeout) #endif #if SYZ_EXECUTOR || SYZ_USE_BITMASKS -#define BITMASK_LEN(type, bf_len) (type)((1ull << (bf_len)) - 1) - -#define BITMASK_LEN_OFF(type, bf_off, bf_len) (type)(BITMASK_LEN(type, (bf_len)) << (bf_off)) - -#define STORE_BY_BITMASK(type, addr, val, bf_off, bf_len) \ - if ((bf_off) == 0 && (bf_len) == 0) { \ - *(type*)(addr) = (type)(val); \ - } else { \ - type new_val = *(type*)(addr); \ - new_val &= ~BITMASK_LEN_OFF(type, (bf_off), (bf_len)); \ - new_val |= ((type)(val)&BITMASK_LEN(type, (bf_len))) << (bf_off); \ - *(type*)(addr) = new_val; \ - } +#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) +#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len) \ + *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | \ + (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) #endif #if SYZ_EXECUTOR || SYZ_USE_CHECKSUMS @@ -3945,7 +3936,10 @@ static long syz_compare(long want, long want_len, long got, long got_len) return -1; } if (memcmp((void*)want, (void*)got, want_len)) { - debug("syz_compare: data differs\n"); + debug("syz_compare: data differs, want:\n"); + debug_dump_data((char*)want, want_len); + debug("got:\n"); + debug_dump_data((char*)got, got_len); errno = EINVAL; return -1; } @@ -4106,7 +4100,10 @@ static long syz_compare(long want, long want_len, long got, long got_len) return -1; } if (memcmp((void*)want, (void*)got, want_len)) { - debug("syz_compare: data differs\n"); + debug("syz_compare: data differs, want:\n"); + debug_dump_data((char*)want, want_len); + debug("got:\n"); + debug_dump_data((char*)got, got_len); errno = EINVAL; return -1; } |
