summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-07-12 16:24:30 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-07-12 16:24:30 -0600
commit54ba669b644f13c158fcbbde76943543eaf66e0a (patch)
treeecfeda5df17525782cdbe1e40f5c1330b9832237 /lib
parent2f28e21aef9be5755fa5f175bb74c9aa6548d1cc (diff)
lib/btrfs: Fuzz the Node parser
Diffstat (limited to 'lib')
-rw-r--r--lib/binstruct/structs.go5
-rw-r--r--lib/btrfs/testdata/fuzz/FuzzRoundTripNode/582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed42
-rw-r--r--lib/btrfs/testdata/fuzz/FuzzRoundTripNode/8260b6cf3bc57fc7d7603487337411d9557684e849ee9457d40f8f3e5f5b2fca2
-rw-r--r--lib/btrfs/testdata/fuzz/FuzzRoundTripNode/9863f0d39958aa548ca8fa512ea6df2f483f3ffce6be73cee08059ca0bd7e8b52
-rw-r--r--lib/btrfs/testdata/fuzz/FuzzRoundTripNode/e748e617b5b662a80f342aeda2fd101ca74ccf3bda0faae115ac338d47f195e92
-rw-r--r--lib/btrfs/types_node.go8
-rw-r--r--lib/btrfs/types_node_test.go35
7 files changed, 56 insertions, 0 deletions
diff --git a/lib/binstruct/structs.go b/lib/binstruct/structs.go
index 72fd5e5..9bc556c 100644
--- a/lib/binstruct/structs.go
+++ b/lib/binstruct/structs.go
@@ -9,6 +9,8 @@ import (
"reflect"
"strconv"
"strings"
+
+ "git.lukeshu.com/btrfs-progs-ng/lib/binstruct/binutil"
)
type End struct{}
@@ -70,6 +72,9 @@ type structField struct {
}
func (sh structHandler) Unmarshal(dat []byte, dst reflect.Value) (int, error) {
+ if err := binutil.NeedNBytes(dat, sh.Size); err != nil {
+ return 0, fmt.Errorf("struct %q %w", sh.name, err)
+ }
var n int
for i, field := range sh.fields {
if field.skip {
diff --git a/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4
new file mode 100644
index 0000000..a96f559
--- /dev/null
+++ b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("0")
diff --git a/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/8260b6cf3bc57fc7d7603487337411d9557684e849ee9457d40f8f3e5f5b2fca b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/8260b6cf3bc57fc7d7603487337411d9557684e849ee9457d40f8f3e5f5b2fca
new file mode 100644
index 0000000..d5c153f
--- /dev/null
+++ b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/8260b6cf3bc57fc7d7603487337411d9557684e849ee9457d40f8f3e5f5b2fca
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\x00\x00\x00\x000")
diff --git a/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/9863f0d39958aa548ca8fa512ea6df2f483f3ffce6be73cee08059ca0bd7e8b5 b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/9863f0d39958aa548ca8fa512ea6df2f483f3ffce6be73cee08059ca0bd7e8b5
new file mode 100644
index 0000000..6a2309e
--- /dev/null
+++ b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/9863f0d39958aa548ca8fa512ea6df2f483f3ffce6be73cee08059ca0bd7e8b5
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("00000000000000000000000000000000000000000000000000000000")
diff --git a/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/e748e617b5b662a80f342aeda2fd101ca74ccf3bda0faae115ac338d47f195e9 b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/e748e617b5b662a80f342aeda2fd101ca74ccf3bda0faae115ac338d47f195e9
new file mode 100644
index 0000000..50b960e
--- /dev/null
+++ b/lib/btrfs/testdata/fuzz/FuzzRoundTripNode/e748e617b5b662a80f342aeda2fd101ca74ccf3bda0faae115ac338d47f195e9
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
diff --git a/lib/btrfs/types_node.go b/lib/btrfs/types_node.go
index 9f20ea9..f425460 100644
--- a/lib/btrfs/types_node.go
+++ b/lib/btrfs/types_node.go
@@ -128,9 +128,17 @@ func (node *Node) UnmarshalBinary(nodeBuf []byte) (int, error) {
Size: uint32(len(nodeBuf)),
ChecksumType: node.ChecksumType,
}
+ if len(nodeBuf) <= binstruct.StaticSize(NodeHeader{}) {
+ return 0, fmt.Errorf("size must be greater than %v, but is %v",
+ binstruct.StaticSize(NodeHeader{}),
+ len(nodeBuf))
+ }
n, err := binstruct.Unmarshal(nodeBuf, &node.Head)
if err != nil {
return n, err
+ } else if n != binstruct.StaticSize(NodeHeader{}) {
+ return n, fmt.Errorf("header consumed %v bytes but expected %v",
+ n, binstruct.StaticSize(NodeHeader{}))
}
if node.Head.Level > 0 {
_n, err := node.unmarshalInternal(nodeBuf[n:])
diff --git a/lib/btrfs/types_node_test.go b/lib/btrfs/types_node_test.go
new file mode 100644
index 0000000..2748c38
--- /dev/null
+++ b/lib/btrfs/types_node_test.go
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package btrfs_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "git.lukeshu.com/btrfs-progs-ng/lib/binstruct"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfs"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfssum"
+)
+
+func FuzzRoundTripNode(f *testing.F) {
+ f.Fuzz(func(t *testing.T, inDat []byte) {
+ t.Logf("dat=(%d)%q", len(inDat), inDat)
+ node := btrfs.Node{
+ ChecksumType: btrfssum.TYPE_CRC32,
+ }
+ n, err := binstruct.Unmarshal(inDat, &node)
+ if err != nil {
+ t.Logf("err=%v", err)
+ //require.Equal(t, 0, n)
+ } else {
+ require.Equal(t, len(inDat), n)
+
+ outDat, err := binstruct.Marshal(node)
+ require.NoError(t, err)
+ require.Equal(t, inDat[:], outDat)
+ }
+ })
+}