Skip to content

Commit 4d38db7

Browse files
committed
route: don't crash or hang up with corrupted messages
Fixes golang/go#16438. Change-Id: I2a97e57cae298e8eecdd5637c9e03493a449fc62 Reviewed-on: https://go-review.googlesource.com/25070 Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
1 parent 3797cd8 commit 4d38db7

File tree

6 files changed

+63
-11
lines changed

6 files changed

+63
-11
lines changed

route/address.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,15 +234,23 @@ func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) (
234234
return nil, err
235235
}
236236
as[i] = a
237-
b = b[roundup(int(b[0])):]
237+
l := roundup(int(b[0]))
238+
if len(b) < l {
239+
return nil, errMessageTooShort
240+
}
241+
b = b[l:]
238242
case sysAF_INET, sysAF_INET6:
239243
af = int(b[1])
240244
a, err := parseInetAddr(af, b)
241245
if err != nil {
242246
return nil, err
243247
}
244248
as[i] = a
245-
b = b[roundup(int(b[0])):]
249+
l := roundup(int(b[0]))
250+
if len(b) < l {
251+
return nil, errMessageTooShort
252+
}
253+
b = b[l:]
246254
default:
247255
l, a, err := fn(af, b)
248256
if err != nil {
@@ -262,7 +270,11 @@ func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) (
262270
return nil, err
263271
}
264272
as[i] = a
265-
b = b[roundup(int(b[0])):]
273+
l := roundup(int(b[0]))
274+
if len(b) < l {
275+
return nil, errMessageTooShort
276+
}
277+
b = b[l:]
266278
}
267279
}
268280
return as[:], nil

route/interface_freebsd.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ func (w *wireFormat) parseInterfaceMessage(typ RIBType, b []byte) (Message, erro
1313
extOff = int(nativeEndian.Uint16(b[18:20]))
1414
bodyOff = int(nativeEndian.Uint16(b[16:18]))
1515
} else {
16-
if len(b) < w.bodyOff {
17-
return nil, errMessageTooShort
18-
}
1916
extOff = w.extOff
2017
bodyOff = w.bodyOff
2118
}
19+
if len(b) < extOff || len(b) < bodyOff {
20+
return nil, errInvalidMessage
21+
}
2222
l := int(nativeEndian.Uint16(b[:2]))
2323
if len(b) < l {
2424
return nil, errInvalidMessage
@@ -53,11 +53,11 @@ func (w *wireFormat) parseInterfaceAddrMessage(typ RIBType, b []byte) (Message,
5353
}
5454
bodyOff = int(nativeEndian.Uint16(b[16:18]))
5555
} else {
56-
if len(b) < w.bodyOff {
57-
return nil, errMessageTooShort
58-
}
5956
bodyOff = w.bodyOff
6057
}
58+
if len(b) < bodyOff {
59+
return nil, errInvalidMessage
60+
}
6161
l := int(nativeEndian.Uint16(b[:2]))
6262
if len(b) < l {
6363
return nil, errInvalidMessage

route/interface_openbsd.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ func (*wireFormat) parseInterfaceMessage(_ RIBType, b []byte) (Message, error) {
2424
Addrs: make([]Addr, sysRTAX_MAX),
2525
raw: b[:l],
2626
}
27-
a, err := parseLinkAddr(b[int(nativeEndian.Uint16(b[4:6])):])
27+
ll := int(nativeEndian.Uint16(b[4:6]))
28+
if len(b) < ll {
29+
return nil, errInvalidMessage
30+
}
31+
a, err := parseLinkAddr(b[ll:])
2832
if err != nil {
2933
return nil, err
3034
}
@@ -42,6 +46,9 @@ func (*wireFormat) parseInterfaceAddrMessage(_ RIBType, b []byte) (Message, erro
4246
return nil, errInvalidMessage
4347
}
4448
bodyOff := int(nativeEndian.Uint16(b[4:6]))
49+
if len(b) < bodyOff {
50+
return nil, errInvalidMessage
51+
}
4552
m := &InterfaceAddrMessage{
4653
Version: int(b[2]),
4754
Type: int(b[3]),

route/message.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ func ParseRIB(typ RIBType, b []byte) ([]Message, error) {
4242
for len(b) > 4 {
4343
nmsgs++
4444
l := int(nativeEndian.Uint16(b[:2]))
45+
if l == 0 {
46+
return nil, errInvalidMessage
47+
}
48+
if len(b) < l {
49+
return nil, errMessageTooShort
50+
}
4551
if b[2] != sysRTM_VERSION {
4652
b = b[l:]
4753
continue

route/message_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,26 @@ func TestMonitorAndParseRIB(t *testing.T) {
9393
time.Sleep(200 * time.Millisecond)
9494
}
9595
}
96+
97+
func TestParseRIBWithFuzz(t *testing.T) {
98+
for _, fuzz := range []string{
99+
"0\x00\x05\x050000000000000000" +
100+
"00000000000000000000" +
101+
"00000000000000000000" +
102+
"00000000000000000000" +
103+
"0000000000000\x02000000" +
104+
"00000000",
105+
"\x02\x00\x05\f0000000000000000" +
106+
"0\x0200000000000000",
107+
"\x02\x00\x05\x100000000000000\x1200" +
108+
"0\x00\xff\x00",
109+
"\x02\x00\x05\f0000000000000000" +
110+
"0\x12000\x00\x02\x0000",
111+
"\x00\x00\x00\x01\x00",
112+
"00000",
113+
} {
114+
for typ := RIBType(0); typ < 256; typ++ {
115+
ParseRIB(typ, []byte(fuzz))
116+
}
117+
}
118+
}

route/route_openbsd.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ func (*wireFormat) parseRouteMessage(_ RIBType, b []byte) (Message, error) {
1919
Index: int(nativeEndian.Uint16(b[6:8])),
2020
raw: b[:l],
2121
}
22-
as, err := parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[int(nativeEndian.Uint16(b[4:6])):])
22+
ll := int(nativeEndian.Uint16(b[4:6]))
23+
if len(b) < ll {
24+
return nil, errInvalidMessage
25+
}
26+
as, err := parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[ll:])
2327
if err != nil {
2428
return nil, err
2529
}

0 commit comments

Comments
 (0)