From ae5ed0b14052adc4be0d98e5e8a46a0b0ab2c565 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 20 Dec 2019 13:57:42 +0100 Subject: pkg/compiler: fix bitfield layout bug Fixes #1542 Found thanks to syz-check. Update #590 --- prog/any_test.go | 2 +- prog/encodingexec.go | 1 + prog/encodingexec_test.go | 24 ++++++++++++------------ prog/types.go | 18 ++++++++++++++---- 4 files changed, 28 insertions(+), 17 deletions(-) (limited to 'prog') diff --git a/prog/any_test.go b/prog/any_test.go index 4e162258c..eaa5bddf6 100644 --- a/prog/any_test.go +++ b/prog/any_test.go @@ -45,7 +45,7 @@ func TestSquash(t *testing.T) { }{ { `foo$any0(&(0x7f0000000000)={0x11, 0x11223344, 0x2233, 0x1122334455667788, {0x1, 0x7, 0x1, 0x1, 0x1bc, 0x4}, [{0x0, @res32=0x0, 0x0, @i8=0x44, "aabb"}, {0x0, @res64=0x1, 0x0, @i32=0x11223344, "1122334455667788"}]})`, - `foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="1100000044332211223300000000000088776655443322113d0079230000000000000000", @ANYRES32=0x0, @ANYBLOB="00000000000000000000000044aabb000000000000000000", @ANYRES64=0x1, @ANYBLOB="000000000000000044332211112233445566778800000000"])`, + `foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="1100000044332211223300000000000088776655443322117d00bc110000000000000000", @ANYRES32=0x0, @ANYBLOB="00000000000000000000000044aabb000000000000000000", @ANYRES64=0x1, @ANYBLOB="000000000000000044332211112233445566778800000000"])`, }, } for i, test := range tests { diff --git a/prog/encodingexec.go b/prog/encodingexec.go index 2e69f2116..45fb2d75e 100644 --- a/prog/encodingexec.go +++ b/prog/encodingexec.go @@ -125,6 +125,7 @@ func (w *execContext) writeCopyin(c *Call) { return } addr := w.target.PhysicalAddr(ctx.Base) + ctx.Offset + addr -= arg.Type().UnitOffset() if w.willBeUsed(arg) { w.args[arg] = argInfo{Addr: addr} } diff --git a/prog/encodingexec_test.go b/prog/encodingexec_test.go index 7a5c066b8..6e2e5f61f 100644 --- a/prog/encodingexec_test.go +++ b/prog/encodingexec_test.go @@ -249,10 +249,10 @@ func TestSerializeForExec(t *testing.T) { execInstrCopyin, dataOffset + 8, execArgConst, 8, 0x42, execInstrCopyin, dataOffset + 16, execArgConst, 2 | 0<<16 | 5<<24, 0x42, execInstrCopyin, dataOffset + 16, execArgConst, 2 | 5<<16 | 6<<24, 0x42, - execInstrCopyin, dataOffset + 20, execArgConst, 4 | 0<<16 | 15<<24, 0x42, - execInstrCopyin, dataOffset + 24, execArgConst, 2 | 0<<16 | 11<<24, 0x42, - execInstrCopyin, dataOffset + 26, execArgConst, 2 | 1<<8 | 0<<16 | 11<<24, 0x42, - execInstrCopyin, dataOffset + 28, execArgConst, 1, 0x42, + execInstrCopyin, dataOffset + 16, execArgConst, 4 | 11<<16 | 15<<24, 0x42, + execInstrCopyin, dataOffset + 20, execArgConst, 2 | 0<<16 | 11<<24, 0x42, + execInstrCopyin, dataOffset + 22, execArgConst, 2 | 1<<8 | 0<<16 | 11<<24, 0x42, + execInstrCopyin, dataOffset + 24, execArgConst, 1, 0x42, callID("test$bf0"), ExecNoCopyout, 1, execArgConst, ptrSize, dataOffset, execInstrEOF, }, @@ -303,16 +303,16 @@ func TestSerializeForExec(t *testing.T) { }, }, { - Addr: dataOffset + 20, + Addr: dataOffset + 16, Arg: ExecArgConst{ Size: 4, Value: 0x42, - BitfieldOffset: 0, + BitfieldOffset: 11, BitfieldLength: 15, }, }, { - Addr: dataOffset + 24, + Addr: dataOffset + 20, Arg: ExecArgConst{ Size: 2, Value: 0x42, @@ -321,7 +321,7 @@ func TestSerializeForExec(t *testing.T) { }, }, { - Addr: dataOffset + 26, + Addr: dataOffset + 22, Arg: ExecArgConst{ Size: 2, Format: FormatBigEndian, @@ -331,7 +331,7 @@ func TestSerializeForExec(t *testing.T) { }, }, { - Addr: dataOffset + 28, + Addr: dataOffset + 24, Arg: ExecArgConst{ Size: 1, Value: 0x42, @@ -394,9 +394,9 @@ func TestSerializeForExec(t *testing.T) { execInstrCopyin, dataOffset + 0, execArgConst, 1 | 0<<16 | 1<<24, 0x1, execInstrCopyin, dataOffset + 0, execArgConst, 1 | 1<<16 | 1<<24, 0x2, execInstrCopyin, dataOffset + 0, execArgConst, 1 | 2<<16 | 1<<24, 0x3, - execInstrCopyin, dataOffset + 1, execArgConst, 2 | 0<<16 | 1<<24, 0x4, - execInstrCopyin, dataOffset + 1, execArgConst, 2 | 1<<16 | 1<<24, 0x5, - execInstrCopyin, dataOffset + 1, execArgConst, 2 | 2<<16 | 1<<24, 0x6, + execInstrCopyin, dataOffset + 0, execArgConst, 2 | 3<<16 | 1<<24, 0x4, + execInstrCopyin, dataOffset + 0, execArgConst, 2 | 4<<16 | 1<<24, 0x5, + execInstrCopyin, dataOffset + 0, execArgConst, 2 | 5<<16 | 1<<24, 0x6, execInstrCopyin, dataOffset + 8, execArgConst, 1, 0x42, callID("test$align7"), ExecNoCopyout, 1, execArgConst, ptrSize, dataOffset, execInstrEOF, diff --git a/prog/types.go b/prog/types.go index 6b2d37e07..0d9bb1604 100644 --- a/prog/types.go +++ b/prog/types.go @@ -65,6 +65,7 @@ type Type interface { // These are different only for all but last bitfield in the group, // where Size == 0 and UnitSize equals to the underlying bitfield type size. UnitSize() uint64 + UnitOffset() uint64 DefaultArg() Arg isDefaultArg(arg Arg) bool @@ -134,6 +135,10 @@ func (t *TypeCommon) UnitSize() uint64 { return t.Size() } +func (t *TypeCommon) UnitOffset() uint64 { + return 0 +} + func (t *TypeCommon) IsBitfield() bool { return false } @@ -189,10 +194,11 @@ func (t *ResourceType) Format() BinaryFormat { type IntTypeCommon struct { TypeCommon - ArgFormat BinaryFormat - BitfieldOff uint64 - BitfieldLen uint64 - BitfieldUnit uint64 + ArgFormat BinaryFormat + BitfieldOff uint64 + BitfieldLen uint64 + BitfieldUnit uint64 + BitfieldUnitOff uint64 } func (t *IntTypeCommon) String() string { @@ -231,6 +237,10 @@ func (t *IntTypeCommon) UnitSize() uint64 { return t.Size() } +func (t *IntTypeCommon) UnitOffset() uint64 { + return t.BitfieldUnitOff +} + func (t *IntTypeCommon) IsBitfield() bool { return t.BitfieldLen != 0 } -- cgit mrf-deployment