blob: b533f95c3afa88575479252a3187839c7f3493b5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
// Copyright 2025 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package kfuzztest
import (
"debug/elf"
"fmt"
)
// The parsableFromBytes interface describes a kftf object that can be parsed
// from a vmlinux binary. All objects are expected to satisfy the following
// constraints
// - Must be statically sized. I.e. the size() function should return some
// fixed value
// - Densely packed: size must exactly describe the number of bytes between
// the start address of instance i and that of instance i+1.
//
// No further assumptions are made about the semantics of the object. For
// example if some field is a pointer to a string (*const char) this will not
// be read from the binary. This responsibility is offloaded to the caller.
type parsableFromBytes interface {
fromBytes(elfFile *elf.File, data []byte) error
size() uint64
startSymbol() string
endSymbol() string
}
type kfuzztestTarget struct {
name uint64
argType uint64
writeCb uint64
readCb uint64
}
const kfuzztestTargetStart string = "__kfuzztest_targets_start"
const kfuzztestTargetEnd string = "__kfuzztest_targets_end"
const kfuzztestTargetSize uint64 = 32
func incorrectByteSizeErr(expected, actual uint64) error {
return fmt.Errorf("incorrect number of bytes: expected %d, got %d", expected, actual)
}
func (targ *kfuzztestTarget) fromBytes(elfFile *elf.File, data []byte) error {
if targ.size() != uint64(len(data)) {
return incorrectByteSizeErr(targ.size(), uint64(len(data)))
}
targ.name = elfFile.ByteOrder.Uint64(data[0:8])
targ.argType = elfFile.ByteOrder.Uint64(data[8:16])
targ.writeCb = elfFile.ByteOrder.Uint64(data[16:24])
targ.readCb = elfFile.ByteOrder.Uint64(data[24:32])
return nil
}
func (targ *kfuzztestTarget) size() uint64 {
return kfuzztestTargetSize
}
func (targ *kfuzztestTarget) startSymbol() string {
return kfuzztestTargetStart
}
func (targ *kfuzztestTarget) endSymbol() string {
return kfuzztestTargetEnd
}
type kfuzztestConstraint struct {
inputType uint64
fieldName uint64
value1 uintptr
value2 uintptr
constraintType uint8
}
const kfuzztestConstraintStart string = "__kfuzztest_constraints_start"
const kfuzztestConstraintEnd string = "__kfuzztest_constraints_end"
const kfuzztestConstraintSize uint64 = 64
func (c *kfuzztestConstraint) fromBytes(elfFile *elf.File, data []byte) error {
if c.size() != uint64(len(data)) {
return incorrectByteSizeErr(c.size(), uint64(len(data)))
}
constraintTypeBytes := elfFile.ByteOrder.Uint64(data[32:40])
c.inputType = elfFile.ByteOrder.Uint64(data[0:8])
c.fieldName = elfFile.ByteOrder.Uint64(data[8:16])
c.value1 = uintptr(elfFile.ByteOrder.Uint64(data[16:24]))
c.value2 = uintptr(elfFile.ByteOrder.Uint64(data[24:32]))
c.constraintType = uint8(constraintTypeBytes & 0xFF)
return nil
}
func (c *kfuzztestConstraint) size() uint64 {
return kfuzztestConstraintSize
}
func (c *kfuzztestConstraint) startSymbol() string {
return kfuzztestConstraintStart
}
func (c *kfuzztestConstraint) endSymbol() string {
return kfuzztestConstraintEnd
}
type kfuzztestAnnotation struct {
inputType uint64
fieldName uint64
linkedFieldName uint64
annotationAttribute uint8
}
func (a *kfuzztestAnnotation) fromBytes(elfFile *elf.File, data []byte) error {
if a.size() != uint64(len(data)) {
return incorrectByteSizeErr(a.size(), uint64(len(data)))
}
a.inputType = elfFile.ByteOrder.Uint64(data[0:8])
a.fieldName = elfFile.ByteOrder.Uint64(data[8:16])
a.linkedFieldName = elfFile.ByteOrder.Uint64(data[16:24])
a.annotationAttribute = data[24]
return nil
}
const kftfAnnotationStart string = "__kfuzztest_annotations_start"
const kftfAnnotationEnd string = "__kfuzztest_annotations_end"
const kftfAnnotationSize uint64 = 32
func (a *kfuzztestAnnotation) size() uint64 {
return kftfAnnotationSize
}
func (a *kfuzztestAnnotation) startSymbol() string {
return kftfAnnotationStart
}
func (a *kfuzztestAnnotation) endSymbol() string {
return kftfAnnotationEnd
}
|