Skip to content

Commit 0c36f8f

Browse files
oncillazombiezen
authored andcommitted
capnp: avoid panics on invalid input (#139)
This PR prevents code from panicking and fixes some small errors during unpacking: Prevents malformed input for composite lists to cause the pogs library to panic. Make the `packed.Decoder` throw an error if the input is `0x00`. According to the spec, at least one more byte is required. Make the `packet.Decoder` throw an error if the input for the unpacked bytes (`0xFF` tag) does not contain enough unpacked bytes. Additionally, update the go/gazelle rules and update the bazel version on CI. Fixes #137
1 parent e1ae1f9 commit 0c36f8f

File tree

8 files changed

+52
-19
lines changed

8 files changed

+52
-19
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
CloudFlare Inc.
1414
Daniel Darabos <[email protected]>
15+
Dominik Roos <[email protected]>
1516
Eran Duchan <[email protected]>
1617
Evan Shaw <[email protected]>
1718
Google Inc.

CONTRIBUTORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
Alan Braithwaite <[email protected]>
1919
Albert Strasheim <[email protected]>
2020
Daniel Darabos <[email protected]>
21+
Dominik Roos <[email protected]>
2122
Eran Duchan <[email protected]>
2223
Evan Shaw <[email protected]>
2324
Ian Denhardt <[email protected]>

WORKSPACE

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
44

55
http_archive(
66
name = "io_bazel_rules_go",
7-
sha256 = "8b68d0630d63d95dacc0016c3bb4b76154fe34fca93efd65d1c366de3fcb4294",
8-
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.12.1/rules_go-0.12.1.tar.gz"],
7+
sha256 = "86ae934bd4c43b99893fc64be9d9fc684b81461581df7ea8fc291c816f5ee8c5",
8+
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.18.3/rules_go-0.18.3.tar.gz"],
99
)
1010

1111
http_archive(
1212
name = "bazel_gazelle",
13-
sha256 = "ddedc7aaeb61f2654d7d7d4fd7940052ea992ccdb031b8f9797ed143ac7e8d43",
14-
urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.12.0/bazel-gazelle-0.12.0.tar.gz"],
13+
sha256 = "3c681998538231a2d24d0c07ed5a7658cb72bfb5fd4bf9911157c0e9ac6a2687",
14+
urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.17.0/bazel-gazelle-0.17.0.tar.gz"],
1515
)
1616

17-
load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_dependencies")
17+
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
1818

1919
go_rules_dependencies()
2020

_travis/install.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ die() {
1313
if [[ -z "$USE_BAZEL" || "$USE_BAZEL" -eq "0" ]]; then
1414
must go get -t ./...
1515
else
16-
BAZEL_VERSION="${BAZEL_VERSION:-0.14.1}"
16+
BAZEL_VERSION="${BAZEL_VERSION:-0.25.0}"
1717
case "$TRAVIS_OS_NAME" in
1818
linux)
1919
BAZEL_INSTALLER_URL="https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-installer-linux-x86_64.sh"

capn.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ func (s *Segment) readListPtr(base Address, val rawPointer) (List, error) {
200200
}
201201
sz := hdr.structSize()
202202
n := int32(hdr.offset())
203+
if n < 0 {
204+
return List{}, errListSize
205+
}
203206
// TODO(light): check that this has the same end address
204207
if tsize, ok := sz.totalSize().times(n); !ok {
205208
return List{}, errOverflow
@@ -214,19 +217,23 @@ func (s *Segment) readListPtr(base Address, val rawPointer) (List, error) {
214217
flags: isCompositeList,
215218
}, nil
216219
}
220+
n := val.numListElements()
221+
if n < 0 {
222+
return List{}, errListSize
223+
}
217224
if lt == bit1List {
218225
return List{
219226
seg: s,
220227
off: addr,
221-
length: val.numListElements(),
228+
length: n,
222229
flags: isBitList,
223230
}, nil
224231
}
225232
return List{
226233
seg: s,
227234
size: val.elementSize(),
228235
off: addr,
229-
length: val.numListElements(),
236+
length: n,
230237
}, nil
231238
}
232239

internal/packed/packed.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ func Unpack(dst, src []byte) ([]byte, error) {
142142
dst = allocWords(dst, int(src[0]))
143143
src = src[1:]
144144
n := copy(dst[start:], src)
145+
if n < len(dst)-start {
146+
return dst, io.ErrUnexpectedEOF
147+
}
145148
src = src[n:]
146149
}
147150
}
@@ -281,22 +284,22 @@ func (r *Reader) ReadWord(p []byte) error {
281284
switch tag {
282285
case zeroTag:
283286
z, err := r.rd.ReadByte()
284-
if err == io.EOF {
285-
r.err = io.ErrUnexpectedEOF
286-
return nil
287-
} else if err != nil {
287+
if err != nil {
288+
if err == io.EOF {
289+
err = io.ErrUnexpectedEOF
290+
}
288291
r.err = err
289-
return nil
292+
return err
290293
}
291294
r.zeroes = int(z)
292295
case unpackedTag:
293296
l, err := r.rd.ReadByte()
294-
if err == io.EOF {
295-
r.err = io.ErrUnexpectedEOF
296-
return nil
297-
} else if err != nil {
297+
if err != nil {
298+
if err == io.EOF {
299+
err = io.ErrUnexpectedEOF
300+
}
298301
r.err = err
299-
return nil
302+
return err
300303
}
301304
r.literal = int(l)
302305
}

internal/packed/packed_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,27 @@ var badDecompressionTests = []struct {
222222
name string
223223
input []byte
224224
}{
225+
{
226+
"short zero tag",
227+
[]byte{0x00},
228+
},
229+
{
230+
"short unpacked tag",
231+
[]byte{0xFF},
232+
},
233+
{
234+
"unpacked tag, only one word",
235+
[]byte{
236+
0xFF, 0, 0, 0, 0, 0, 0, 0, 0,
237+
},
238+
},
239+
{
240+
"unpacked tag, short unpacked word",
241+
[]byte{
242+
0xFF, 0, 0, 0, 0, 0, 0, 0, 0,
243+
0x01, 0,
244+
},
245+
},
225246
{
226247
"wrong tag",
227248
[]byte{

pointer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func (p Ptr) text() (b []byte, ok bool) {
155155
// Text must be null-terminated.
156156
return nil, false
157157
}
158-
return b[:len(b)-1 : len(b)], true
158+
return b[: len(b)-1 : len(b)], true
159159
}
160160

161161
// Data attempts to convert p into Data, returning nil if p is not a

0 commit comments

Comments
 (0)