diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2019-12-20 13:57:42 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-12-20 16:45:34 +0100 |
| commit | ae5ed0b14052adc4be0d98e5e8a46a0b0ab2c565 (patch) | |
| tree | 162cebcc1f8d487399415f1b11ac9738fabd7ec7 /prog | |
| parent | 4bba9fd1629d5351877b21fc662a125342a18a9e (diff) | |
pkg/compiler: fix bitfield layout bug
Fixes #1542
Found thanks to syz-check. Update #590
Diffstat (limited to 'prog')
| -rw-r--r-- | prog/any_test.go | 2 | ||||
| -rw-r--r-- | prog/encodingexec.go | 1 | ||||
| -rw-r--r-- | prog/encodingexec_test.go | 24 | ||||
| -rw-r--r-- | prog/types.go | 18 |
4 files changed, 28 insertions, 17 deletions
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 } |
