Skip to content

Commit 0a6e5e6

Browse files
authored
Merge pull request kubernetes#83750 from mwwolters/json_fuzz
A go-fuzz target for Serializer.Encode/Decode, tested with go-fuzz
2 parents aab740f + 78c57cb commit 0a6e5e6

File tree

3 files changed

+181
-0
lines changed

3 files changed

+181
-0
lines changed

test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ filegroup(
1717
"//test/e2e_kubeadm:all-srcs",
1818
"//test/e2e_node:all-srcs",
1919
"//test/fixtures:all-srcs",
20+
"//test/fuzz/json:all-srcs",
2021
"//test/fuzz/yaml:all-srcs",
2122
"//test/images:all-srcs",
2223
"//test/instrumentation:all-srcs",

test/fuzz/json/BUILD

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["json.go"],
6+
importpath = "k8s.io/kubernetes/test/fuzz/json",
7+
visibility = ["//visibility:private"],
8+
deps = [
9+
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
10+
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
11+
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
12+
],
13+
)
14+
15+
filegroup(
16+
name = "package-srcs",
17+
srcs = glob(["**"]),
18+
tags = ["automanaged"],
19+
visibility = ["//visibility:private"],
20+
)
21+
22+
filegroup(
23+
name = "all-srcs",
24+
srcs = [":package-srcs"],
25+
tags = ["automanaged"],
26+
visibility = ["//visibility:public"],
27+
)

test/fuzz/json/json.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
Copyright 2019 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package json implements fuzzers for json deserialization routines in
18+
// Kubernetes. These targets are compatible with the github.com/dvyukov/go-fuzz
19+
// fuzzing framework.
20+
package json
21+
22+
import (
23+
"bytes"
24+
"k8s.io/apimachinery/pkg/runtime"
25+
"k8s.io/apimachinery/pkg/runtime/schema"
26+
"k8s.io/apimachinery/pkg/runtime/serializer/json"
27+
)
28+
29+
var (
30+
gvk = &schema.GroupVersionKind{Version: "v1"}
31+
strictOpt = json.SerializerOptions{Yaml: false, Pretty: false, Strict: true}
32+
strictYamlOpt = json.SerializerOptions{Yaml: true, Pretty: false, Strict: true}
33+
strictPrettyOpt = json.SerializerOptions{Yaml: false, Pretty: true, Strict: true}
34+
nonstrictOpt = json.SerializerOptions{Yaml: false, Pretty: false, Strict: false}
35+
nonstrictYamlOpt = json.SerializerOptions{Yaml: true, Pretty: false, Strict: false}
36+
nonstrictPrettyOpt = json.SerializerOptions{Yaml: false, Pretty: true, Strict: false}
37+
scheme = runtime.NewScheme()
38+
strictSer = json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, strictOpt)
39+
ysSer = json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, strictYamlOpt)
40+
psSer = json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, strictPrettyOpt)
41+
nonstrictSer = json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, nonstrictOpt)
42+
ynsSer = json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, nonstrictYamlOpt)
43+
pnsSer = json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, nonstrictPrettyOpt)
44+
)
45+
46+
// FuzzStrictDecode is a fuzz target for "k8s.io/apimachinery/pkg/runtime/serializer/json" strict decoding.
47+
func FuzzStrictDecode(data []byte) int {
48+
obj0, _, err0 := strictSer.Decode(data, gvk, nil)
49+
obj1, _, err1 := nonstrictSer.Decode(data, gvk, nil)
50+
obj2, _, err2 := ysSer.Decode(data, gvk, nil)
51+
obj3, _, err3 := psSer.Decode(data, gvk, nil)
52+
if obj0 == nil {
53+
if obj1 != nil {
54+
panic("NonStrict is stricter than Strict")
55+
}
56+
if obj2 != nil {
57+
panic("Yaml strict different from plain strict")
58+
}
59+
if obj3 != nil {
60+
panic("Pretty strict different from plain strict")
61+
}
62+
if err0 == nil || err1 == nil || err2 == nil || err3 == nil {
63+
panic("no error")
64+
}
65+
return 0
66+
}
67+
68+
if err0 != nil {
69+
panic("got object and error for strict")
70+
}
71+
if err2 != nil {
72+
panic("got object and error for yaml strict")
73+
}
74+
if err3 != nil {
75+
panic("got object and error pretty strict")
76+
}
77+
78+
var b0 bytes.Buffer
79+
err4 := strictSer.Encode(obj0, &b0)
80+
if err4 != nil {
81+
panic("Can't encode decoded data")
82+
}
83+
if !bytes.Equal(b0.Bytes(), data) {
84+
panic("Encoded data doesn't match original")
85+
}
86+
87+
b0.Reset()
88+
err5 := ysSer.Encode(obj1, &b0)
89+
if err5 != nil {
90+
panic("Can't encode yaml strict decoded data")
91+
}
92+
if !bytes.Equal(b0.Bytes(), data) {
93+
panic("Encoded yaml strict data doesn't match original")
94+
}
95+
96+
b0.Reset()
97+
err6 := psSer.Encode(obj2, &b0)
98+
if err6 != nil {
99+
panic("Can't encode pretty strict decoded data")
100+
}
101+
if !bytes.Equal(b0.Bytes(), data) {
102+
panic("Encoded pretty strict data doesn't match original")
103+
}
104+
105+
b0.Reset()
106+
err7 := nonstrictSer.Encode(obj3, &b0)
107+
if err7 != nil {
108+
panic("Can't encode nonstrict decoded data")
109+
}
110+
if !bytes.Equal(b0.Bytes(), data) {
111+
panic("Encoded nonstrict data doesn't match original")
112+
}
113+
return 1
114+
}
115+
116+
// FuzzNonStrictDecode is a fuzz target for "k8s.io/apimachinery/pkg/runtime/serializer/json" non-strict decoding.
117+
func FuzzNonStrictDecode(data []byte) int {
118+
obj0, _, err0 := nonstrictSer.Decode(data, gvk, nil)
119+
if err0 != nil {
120+
return 0
121+
}
122+
123+
var b0 bytes.Buffer
124+
err1 := nonstrictSer.Encode(obj0, &b0)
125+
if err1 != nil {
126+
panic("Can't nonstrict encode decoded data")
127+
}
128+
_, _, err2 := nonstrictSer.Decode(b0.Bytes(), gvk, nil)
129+
if err2 != nil {
130+
panic("Can't nonstrict decode encoded data")
131+
}
132+
133+
b0.Reset()
134+
err3 := ynsSer.Encode(obj0, &b0)
135+
if err3 != nil {
136+
panic("Can't yaml strict encode decoded data")
137+
}
138+
_, _, err4 := nonstrictSer.Decode(b0.Bytes(), gvk, nil)
139+
if err4 != nil {
140+
panic("Can't nonstrict decode encoded data")
141+
}
142+
143+
b0.Reset()
144+
err5 := pnsSer.Encode(obj0, &b0)
145+
if err5 != nil {
146+
panic("Can't pretty strict encode decoded data")
147+
}
148+
_, _, err6 := nonstrictSer.Decode(b0.Bytes(), gvk, nil)
149+
if err6 != nil {
150+
panic("Can't nonstrict decode encoded data")
151+
}
152+
return 1
153+
}

0 commit comments

Comments
 (0)