prometheus

Форк
0
/
fuzz.go 
125 строк · 3.5 Кб
1
// Copyright 2015 The Prometheus Authors
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
// you may not use this file except in compliance with the License.
4
// You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13

14
// Only build when go-fuzz is in use
15
//go:build gofuzz
16

17
package promql
18

19
import (
20
	"errors"
21
	"io"
22

23
	"github.com/prometheus/prometheus/model/labels"
24
	"github.com/prometheus/prometheus/model/textparse"
25
	"github.com/prometheus/prometheus/promql/parser"
26
)
27

28
// PromQL parser fuzzing instrumentation for use with
29
// https://github.com/dvyukov/go-fuzz.
30
//
31
// Fuzz each parser by building appropriately instrumented parser, ex.
32
// FuzzParseMetric and execute it with it's
33
//
34
//     go-fuzz-build -func FuzzParseMetric -o FuzzParseMetric.zip github.com/prometheus/prometheus/promql
35
//
36
// And then run the tests with the appropriate inputs
37
//
38
//     go-fuzz -bin FuzzParseMetric.zip -workdir fuzz-data/ParseMetric
39
//
40
// Further input samples should go in the folders fuzz-data/ParseMetric/corpus.
41
//
42
// Repeat for FuzzParseOpenMetric, FuzzParseMetricSelector and FuzzParseExpr.
43

44
// Tuning which value is returned from Fuzz*-functions has a strong influence
45
// on how quick the fuzzer converges on "interesting" cases. At least try
46
// switching between fuzzMeh (= included in corpus, but not a priority) and
47
// fuzzDiscard (=don't use this input for re-building later inputs) when
48
// experimenting.
49
const (
50
	fuzzInteresting = 1
51
	fuzzMeh         = 0
52
	fuzzDiscard     = -1
53

54
	// Input size above which we know that Prometheus would consume too much
55
	// memory. The recommended way to deal with it is check input size.
56
	// https://google.github.io/oss-fuzz/getting-started/new-project-guide/#input-size
57
	maxInputSize = 10240
58
)
59

60
// Use package-scope symbol table to avoid memory allocation on every fuzzing operation.
61
var symbolTable = labels.NewSymbolTable()
62

63
func fuzzParseMetricWithContentType(in []byte, contentType string) int {
64
	p, warning := textparse.New(in, contentType, false, symbolTable)
65
	if warning != nil {
66
		// An invalid content type is being passed, which should not happen
67
		// in this context.
68
		panic(warning)
69
	}
70

71
	var err error
72
	for {
73
		_, err = p.Next()
74
		if err != nil {
75
			break
76
		}
77
	}
78
	if errors.Is(err, io.EOF) {
79
		err = nil
80
	}
81

82
	if err == nil {
83
		return fuzzInteresting
84
	}
85

86
	return fuzzMeh
87
}
88

89
// Fuzz the metric parser.
90
//
91
// Note that this is not the parser for the text-based exposition-format; that
92
// lives in github.com/prometheus/client_golang/text.
93
func FuzzParseMetric(in []byte) int {
94
	return fuzzParseMetricWithContentType(in, "")
95
}
96

97
func FuzzParseOpenMetric(in []byte) int {
98
	return fuzzParseMetricWithContentType(in, "application/openmetrics-text")
99
}
100

101
// Fuzz the metric selector parser.
102
func FuzzParseMetricSelector(in []byte) int {
103
	if len(in) > maxInputSize {
104
		return fuzzMeh
105
	}
106
	_, err := parser.ParseMetricSelector(string(in))
107
	if err == nil {
108
		return fuzzInteresting
109
	}
110

111
	return fuzzMeh
112
}
113

114
// Fuzz the expression parser.
115
func FuzzParseExpr(in []byte) int {
116
	if len(in) > maxInputSize {
117
		return fuzzMeh
118
	}
119
	_, err := parser.ParseExpr(string(in))
120
	if err == nil {
121
		return fuzzInteresting
122
	}
123

124
	return fuzzMeh
125
}
126

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.