aboutsummaryrefslogtreecommitdiffstats
path: root/tools/syz-check
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2019-12-20 13:57:42 +0100
committerDmitry Vyukov <dvyukov@google.com>2019-12-20 16:45:34 +0100
commitae5ed0b14052adc4be0d98e5e8a46a0b0ab2c565 (patch)
tree162cebcc1f8d487399415f1b11ac9738fabd7ec7 /tools/syz-check
parent4bba9fd1629d5351877b21fc662a125342a18a9e (diff)
pkg/compiler: fix bitfield layout bug
Fixes #1542 Found thanks to syz-check. Update #590
Diffstat (limited to 'tools/syz-check')
-rw-r--r--tools/syz-check/check.go16
1 files changed, 10 insertions, 6 deletions
diff --git a/tools/syz-check/check.go b/tools/syz-check/check.go
index 0582d892c..5bd556516 100644
--- a/tools/syz-check/check.go
+++ b/tools/syz-check/check.go
@@ -171,6 +171,9 @@ func checkStruct(typ *prog.StructDesc, astStruct *ast.Struct, str *dwarf.StructT
warn(astStruct.Pos, "struct %v: bad size: syz=%v kernel=%v", typ.Name(), typ.Size(), str.ByteSize)
}
// TODO: handle unions, currently we should report some false errors.
+ if str.Kind == "union" {
+ return warnings, nil
+ }
// TODO: we could also check enums (elements match corresponding flags in syzkaller).
// TODO: we could also check values of literal constants (dwarf should have that, right?).
ai := 0
@@ -191,24 +194,25 @@ func checkStruct(typ *prog.StructDesc, astStruct *ast.Struct, str *dwarf.StructT
warn(pos, "%v: bad size: syz=%v kernel=%v",
desc, field.UnitSize(), fld.Type.Size())
}
- if offset != uint64(fld.ByteOffset) {
+ byteOffset := offset - field.UnitOffset()
+ if byteOffset != uint64(fld.ByteOffset) {
warn(pos, "%v: bad offset: syz=%v kernel=%v",
- desc, offset, fld.ByteOffset)
+ desc, byteOffset, fld.ByteOffset)
}
// How would you define bitfield offset?
// Offset of the beginning of the field from the beginning of the memory location, right?
// No, DWARF defines it as offset of the end of the field from the end of the memory location.
- offset := fld.Type.Size()*8 - fld.BitOffset - fld.BitSize
+ bitOffset := fld.Type.Size()*8 - fld.BitOffset - fld.BitSize
if fld.BitSize == 0 {
// And to make things even more interesting this calculation
// does not work for normal variables.
- offset = 0
+ bitOffset = 0
}
if field.BitfieldLength() != uint64(fld.BitSize) ||
- field.BitfieldOffset() != uint64(offset) {
+ field.BitfieldOffset() != uint64(bitOffset) {
warn(pos, "%v: bad bit size/offset: syz=%v/%v kernel=%v/%v",
desc, field.BitfieldLength(), field.BitfieldOffset(),
- fld.BitSize, offset)
+ fld.BitSize, bitOffset)
}
}
ai++