Skip to content

Commit 1fbb024

Browse files
committed
Fix netlink TLV parsing for FOU
This fixes a bug that netlink messages for FOU are not correctly deserialized Fix unused var shift Fix incorrect test case
1 parent d3c0a2c commit 1fbb024

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

fou_linux.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build linux
12
// +build linux
23

34
package netlink
@@ -171,36 +172,40 @@ func (h *Handle) FouList(fam int) ([]Fou, error) {
171172
func deserializeFouMsg(msg []byte) (Fou, error) {
172173
// we'll skip to byte 4 to first attribute
173174
msg = msg[3:]
174-
var shift int
175175
fou := Fou{}
176176

177177
for {
178-
// attribute header is at least 16 bits
178+
// attribute header is at least 32 bits (16 bit type + 16 bit length)
179179
if len(msg) < 4 {
180180
return fou, ErrAttrHeaderTruncated
181181
}
182182

183183
lgt := int(binary.BigEndian.Uint16(msg[0:2]))
184-
if len(msg) < lgt+4 {
184+
lgt4 := lgt & (^0x3)
185+
186+
// Padding to 4 bytes according to netlink man7
187+
lgtPad := lgt4 + 4
188+
if lgt4 == lgt {
189+
lgtPad = lgt
190+
}
191+
192+
if len(msg) < lgtPad {
185193
return fou, ErrAttrBodyTruncated
186194
}
187195
attr := binary.BigEndian.Uint16(msg[2:4])
188196

189-
shift = lgt + 3
190197
switch attr {
191198
case FOU_ATTR_AF:
192199
fou.Family = int(msg[5])
193200
case FOU_ATTR_PORT:
194201
fou.Port = int(binary.BigEndian.Uint16(msg[5:7]))
195-
// port is 2 bytes
196-
shift = lgt + 2
197202
case FOU_ATTR_IPPROTO:
198203
fou.Protocol = int(msg[5])
199204
case FOU_ATTR_TYPE:
200205
fou.EncapType = int(msg[5])
201206
}
202207

203-
msg = msg[shift:]
208+
msg = msg[lgtPad:]
204209

205210
if len(msg) < 4 {
206211
break

fou_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build linux
12
// +build linux
23

34
package netlink
@@ -42,7 +43,7 @@ func TestFouDeserializeMsg(t *testing.T) {
4243
}
4344

4445
// deserialize truncated attribute header
45-
msg = []byte{3, 1, 0, 0, 5, 0, 2, 0, 2, 0, 0}
46+
msg = []byte{3, 1, 0, 0, 5, 0, 2, 0, 2, 0}
4647
if _, err := deserializeFouMsg(msg); err == nil {
4748
t.Error("expected attribute body truncated error")
4849
} else if err != ErrAttrBodyTruncated {

0 commit comments

Comments
 (0)