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