lib/protocol: Buffer allocation when compressing (fixes #6146) (#6147)

We incorrectly gave a too small buffer to lz4.Compress, causing it to
allocate in some cases (when the data actually becomes larger when
compressed). This then panicked when passed to the buffer pool.

This ensures a buffer that is large enough, and adds tripwires closer to
the source in case this ever pops up again. There is a test that
exercises the issue.
This commit is contained in:
Jakob Borg
2019-11-11 09:36:31 +01:00
committed by Audrius Butkevicius
parent 1d406d62e3
commit d19b12d3fe
2 changed files with 44 additions and 6 deletions

View File

@@ -959,14 +959,17 @@ func (c *rawConnection) Statistics() Statistics {
func (c *rawConnection) lz4Compress(src []byte) ([]byte, error) {
var err error
buf := BufferPool.Get(len(src))
buf, err = lz4.Encode(buf, src)
buf := BufferPool.Get(lz4.CompressBound(len(src)))
compressed, err := lz4.Encode(buf, src)
if err != nil {
return nil, err
}
if &compressed[0] != &buf[0] {
panic("bug: lz4.Compress allocated, which it must not (should use buffer pool)")
}
binary.BigEndian.PutUint32(buf, binary.LittleEndian.Uint32(buf))
return buf, nil
binary.BigEndian.PutUint32(compressed, binary.LittleEndian.Uint32(compressed))
return compressed, nil
}
func (c *rawConnection) lz4Decompress(src []byte) ([]byte, error) {
@@ -974,9 +977,12 @@ func (c *rawConnection) lz4Decompress(src []byte) ([]byte, error) {
binary.LittleEndian.PutUint32(src, size)
var err error
buf := BufferPool.Get(int(size))
buf, err = lz4.Decode(buf, src)
decoded, err := lz4.Decode(buf, src)
if err != nil {
return nil, err
}
return buf, nil
if &decoded[0] != &buf[0] {
panic("bug: lz4.Decode allocated, which it must not (should use buffer pool)")
}
return decoded, nil
}