Skip to content

Commit

Permalink
zstd: add missing sanity check for output capacity in asm implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
WojciechMula committed Apr 22, 2022
1 parent 88518c9 commit 1206998
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 37 deletions.
38 changes: 38 additions & 0 deletions zstd/_generate/gen.go
Expand Up @@ -34,6 +34,9 @@ const errorMatchOffTooBig = 3
// error reported when the sum of literal lengths exeeceds the literal buffer size
const errorNotEnoughLiterals = 4

// error reported when capacity of `out` is too small
const errorNotEnoughSpace = 5

const maxMatchLen = 131074

// size of struct seqVals
Expand Down Expand Up @@ -199,6 +202,7 @@ func (o options) generateBody(name string, executeSingleTriple func(ctx *execute
ec.llPtr = llP

ec.outBase = GP64()
ec.outEndPtr = AllocLocal(8)
ec.literals = GP64()
ec.outPosition = GP64()
ec.histLenPtr = AllocLocal(8)
Expand All @@ -212,6 +216,7 @@ func (o options) generateBody(name string, executeSingleTriple func(ctx *execute
}

Load(ctx.Field("out").Base(), ec.outBase)
loadField(ctx.Field("out").Cap(), ec.outEndPtr)
Load(ctx.Field("literals").Base(), ec.literals)
Load(ctx.Field("outPosition"), ec.outPosition)
loadField(ctx.Field("windowSize"), ec.windowSizePtr)
Expand All @@ -224,8 +229,12 @@ func (o options) generateBody(name string, executeSingleTriple func(ctx *execute
ADDQ(tmp, ec.histBasePtr) // Note: we always copy from &hist[len(hist) - v]
}

Comment("Calculate poiter to s.out[cap(s.out)] (a past-end pointer)")
ADDQ(ec.outBase, ec.outEndPtr)

Comment("outBase += outPosition")
ADDQ(ec.outPosition, ec.outBase)

}
}

Expand Down Expand Up @@ -465,6 +474,22 @@ func (o options) generateBody(name string, executeSingleTriple func(ctx *execute

o.returnWithCode(errorNotEnoughLiterals)
}

Comment("Return with not enough output space error")
{
Label("error_not_enough_space")
if !o.useSeqs {
ctx := Dereference(Param("ctx"))
tmp := GP64()
MOVQ(llP, tmp)
Store(tmp, ctx.Field("ll"))
MOVQ(mlP, tmp)
Store(tmp, ctx.Field("ml"))
Store(ec.outPosition, ctx.Field("outPosition"))
}

o.returnWithCode(errorNotEnoughSpace)
}
}

func (o options) returnWithCode(returnCode uint32) {
Expand Down Expand Up @@ -1000,6 +1025,7 @@ type executeSingleTripleContext struct {
windowSize reg.GPVirtual

// values used when useSeqs is false
outEndPtr Mem // pointer to s.out[cap(s.out)]
histBasePtr Mem
histLenPtr Mem
windowSizePtr Mem
Expand All @@ -1015,6 +1041,18 @@ func (e executeSimple) executeSingleTriple(c *executeSingleTripleContext, handle
ml := GP64()
MOVQ(c.mlPtr, ml)

if !e.useSeqs {
Comment("Check if we have enough space in s.out")
{
// baseAfterCopy = ll + ml + c.outBese
baseAfterCopy := GP64()
LEAQ(Mem{Base: ll, Index: ml, Scale: 1}, baseAfterCopy)
ADDQ(c.outBase, baseAfterCopy)
CMPQ(baseAfterCopy, c.outEndPtr)
JAE(LabelRef("error_not_enough_space"))
}
}

Comment("Copy literals")
Label("copy_literals")
{
Expand Down
9 changes: 8 additions & 1 deletion zstd/seqdec_amd64.go
Expand Up @@ -121,6 +121,10 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {
return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available",
ctx.ll, ctx.litRemain+ctx.ll)

case errorNotEnoughSpace:
size := ctx.outPosition + ctx.ll + ctx.ml
return true, fmt.Errorf("output (%d) bigger than max block size (%d)", size-startSize, maxBlockSize)

default:
return true, fmt.Errorf("sequenceDecs_decode returned erronous code %d", errCode)
}
Expand Down Expand Up @@ -173,12 +177,15 @@ const errorMatchLenOfsMismatch = 1
// error reported when ml > maxMatchLen
const errorMatchLenTooBig = 2

// error reported when mo > t or mo > s.windowSize
// error reported when mo > available history or mo > s.windowSize
const errorMatchOffTooBig = 3

// error reported when the sum of literal lengths exeeceds the literal buffer size
const errorNotEnoughLiterals = 4

// error reported when capacity of `out` is too small
const errorNotEnoughSpace = 5

// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm.
//
// Please refer to seqdec_generic.go for the reference implementation.
Expand Down

0 comments on commit 1206998

Please sign in to comment.