Skip to content

Commit

Permalink
netlink: add argument length checks to AttributeEncoder calls
Browse files Browse the repository at this point in the history
Updates #191

Signed-off-by: Matt Layher <[email protected]>
  • Loading branch information
mdlayher committed Dec 2, 2021
1 parent 057d5d3 commit fe6002e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
17 changes: 17 additions & 0 deletions attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/binary"
"errors"
"fmt"
"math"

"github.com/josharian/native"
"github.com/mdlayher/netlink/nlenc"
Expand Down Expand Up @@ -619,6 +620,12 @@ func (ae *AttributeEncoder) String(typ uint16, s string) {
return
}

// Length checking, thanks ubiquitousbyte on GitHub.
if len(s) > math.MaxUint16-nlaHeaderLen {
ae.err = errors.New("string is too large to fit in a netlink attribute")
return
}

ae.attrs = append(ae.attrs, Attribute{
Type: typ,
Data: nlenc.Bytes(s),
Expand All @@ -631,6 +638,11 @@ func (ae *AttributeEncoder) Bytes(typ uint16, b []byte) {
return
}

if len(b) > math.MaxUint16-nlaHeaderLen {
ae.err = errors.New("byte slice is too large to fit in a netlink attribute")
return
}

ae.attrs = append(ae.attrs, Attribute{
Type: typ,
Data: b,
Expand All @@ -654,6 +666,11 @@ func (ae *AttributeEncoder) Do(typ uint16, fn func() ([]byte, error)) {
return
}

if len(b) > math.MaxUint16-nlaHeaderLen {
ae.err = errors.New("byte slice produced by Do is too large to fit in a netlink attribute")
return
}

ae.attrs = append(ae.attrs, Attribute{
Type: typ,
Data: b,
Expand Down
23 changes: 22 additions & 1 deletion attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"errors"
"math"
"reflect"
"testing"
"unsafe"
Expand Down Expand Up @@ -957,7 +958,27 @@ func TestAttributeEncoderError(t *testing.T) {
fn func(ae *AttributeEncoder)
}{
{
name: "do",
name: "bytes length",
fn: func(ae *AttributeEncoder) {
ae.Bytes(1, make([]byte, math.MaxUint16))
},
},
{
name: "string length",
fn: func(ae *AttributeEncoder) {
ae.String(1, string(make([]byte, math.MaxUint16)))
},
},
{
name: "do length",
fn: func(ae *AttributeEncoder) {
ae.Do(1, func() ([]byte, error) {
return make([]byte, math.MaxUint16), nil
})
},
},
{
name: "do function",
fn: func(ae *AttributeEncoder) {
ae.Do(1, func() ([]byte, error) {
return nil, errors.New("testing error")
Expand Down

0 comments on commit fe6002e

Please sign in to comment.