From 89a0ab6799895a3d187aea3ab624aabe6c541e2e Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Wed, 4 Jan 2017 00:12:47 +0000 Subject: [PATCH] Fix test data and improve /proc/net/tcp header parsing The header checking code was unsafe because: 1. It was accessing the byteslice at [2] without ensuring a length >= 3 2. It was assuming that the indentation of the 'sl' header is always 2 (which seems to be the case in recent kernels https://github.com/torvalds/linux/blob/8f18e4d03ed8fa5e4a300c94550533bd8ce4ff9a/net/ipv4/tcp_ipv4.c#L2304 and https://github.com/torvalds/linux/blob/8f18e4d03ed8fa5e4a300c94550533bd8ce4ff9a/net/ipv6/tcp_ipv6.c#L1831 ) but it's more robust to simply trim the byteslice. --- probe/endpoint/procspy/procnet.go | 15 +++++++++------ probe/endpoint/procspy/procnet_internal_test.go | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/probe/endpoint/procspy/procnet.go b/probe/endpoint/procspy/procnet.go index 910ba6706..1946d5f6a 100644 --- a/probe/endpoint/procspy/procnet.go +++ b/probe/endpoint/procspy/procnet.go @@ -5,6 +5,9 @@ import ( "net" ) +// Used to check whether we are parsing a header line +var slHeader = []byte("sl") + // ProcNet is an iterator to parse /proc/net/tcp{,6} files. type ProcNet struct { b []byte @@ -31,16 +34,16 @@ again: } b := p.b - if p.b[2] == 's' { + var ( + sl, local, remote, inode []byte + ) + + sl, b = nextField(b) // 'sl' column + if bytes.Equal(sl, slHeader) { // Skip header p.b = nextLine(b) goto again } - - var ( - local, remote, inode []byte - ) - _, b = nextField(b) // 'sl' column local, b = nextField(b) remote, b = nextField(b) _, b = nextField(b) // 'st' column diff --git a/probe/endpoint/procspy/procnet_internal_test.go b/probe/endpoint/procspy/procnet_internal_test.go index 6b34ad858..876282678 100644 --- a/probe/endpoint/procspy/procnet_internal_test.go +++ b/probe/endpoint/procspy/procnet_internal_test.go @@ -59,7 +59,7 @@ func TestProcNet(t *testing.T) { func TestTransport6(t *testing.T) { // Abridged copy of my /proc/net/tcp6 - testString := ` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout Inode + testString := ` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout Inode 0: 00000000000000000000000000000000:19C8 00000000000000000000000000000000:0000 01 00000000:00000000 00:00000000 00000000 0 0 23661201 1 ffff880103fb4800 100 0 0 10 -1 8: 4500032000BE692B8AE31EBD919D9D10:D61C 5014002A080805400000000015100000:01BB 01 00000000:00000000 02:00000045 00000000 1000 0 36856710 2 ffff88010b796080 22 4 30 8 7 `