diff --git a/go.mod b/go.mod index 4b7cb7674..76d646a86 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/containerd/containerd go 1.18 require ( - github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8 + github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72 github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20220912195655-e1f97a00006b github.com/Microsoft/go-winio v0.6.0 github.com/Microsoft/hcsshim v0.10.0-rc.1 diff --git a/go.sum b/go.sum index de1019168..e9c0743be 100644 --- a/go.sum +++ b/go.sum @@ -44,8 +44,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8 h1:d+pBUmsteW5tM87xmVXHZ4+LibHRFn40SPAoZJOg2ak= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8/go.mod h1:i9fr2JpcEcY/IHEvzCM3qXUZYOQHgR89dt4es1CgMhc= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72 h1:kq78byqmxX6R9uk4uN3HD2F5tkZJAZMauuLSkNPS8to= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20220912195655-e1f97a00006b h1:RQhYYLDVbdN+fw4I+A90nMRcxg/tEg4KvHiDYOwY32g= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20220912195655-e1f97a00006b/go.mod h1:P/MhpyNnqWUWlF8b/ksNuhU2kywD3Qc5fzauL06Gez8= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= diff --git a/integration/client/go.mod b/integration/client/go.mod index e5a238762..7b276abd3 100644 --- a/integration/client/go.mod +++ b/integration/client/go.mod @@ -20,7 +20,7 @@ require ( ) require ( - github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8 + github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72 github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774 ) diff --git a/integration/client/go.sum b/integration/client/go.sum index b6fe7cd80..794482db4 100644 --- a/integration/client/go.sum +++ b/integration/client/go.sum @@ -363,8 +363,8 @@ cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vf cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20220824214621-3c06a36a6952/go.mod h1:i9fr2JpcEcY/IHEvzCM3qXUZYOQHgR89dt4es1CgMhc= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8 h1:d+pBUmsteW5tM87xmVXHZ4+LibHRFn40SPAoZJOg2ak= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8/go.mod h1:i9fr2JpcEcY/IHEvzCM3qXUZYOQHgR89dt4es1CgMhc= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72 h1:kq78byqmxX6R9uk4uN3HD2F5tkZJAZMauuLSkNPS8to= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20220912195655-e1f97a00006b h1:RQhYYLDVbdN+fw4I+A90nMRcxg/tEg4KvHiDYOwY32g= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20220912195655-e1f97a00006b/go.mod h1:P/MhpyNnqWUWlF8b/ksNuhU2kywD3Qc5fzauL06Gez8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= diff --git a/vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go b/vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go index 3445d6be3..16200a100 100644 --- a/vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go +++ b/vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go @@ -18,9 +18,7 @@ import ( securejoin "github.com/cyphar/filepath-securejoin" ) -var ( - MaxTotalLen = uint32(2000000) -) +var MaxTotalLen uint32 = 2000000 func SetMaxTotalLen(newLen uint32) { MaxTotalLen = newLen @@ -28,6 +26,7 @@ func SetMaxTotalLen(newLen uint32) { type ConsumeFuzzer struct { data []byte + dataTotal uint32 CommandPart []byte RestOfArray []byte NumberOfCalls int @@ -41,22 +40,23 @@ func IsDivisibleBy(n int, divisibleby int) bool { } func NewConsumer(fuzzData []byte) *ConsumeFuzzer { - fuzzMap := make(map[reflect.Type]reflect.Value) - f := &ConsumeFuzzer{data: fuzzData, position: 0, Funcs: fuzzMap} - return f + return &ConsumeFuzzer{ + data: fuzzData, + dataTotal: uint32(len(fuzzData)), + Funcs: make(map[reflect.Type]reflect.Value), + } } func (f *ConsumeFuzzer) Split(minCalls, maxCalls int) error { - if len(f.data) == 0 { - return errors.New("Could not split") + if f.dataTotal == 0 { + return errors.New("could not split") } numberOfCalls := int(f.data[0]) if numberOfCalls < minCalls || numberOfCalls > maxCalls { - return errors.New("Bad number of calls") - + return errors.New("bad number of calls") } - if len(f.data) < numberOfCalls+numberOfCalls+1 { - return errors.New("Length of data does not match required parameters") + if int(f.dataTotal) < numberOfCalls+numberOfCalls+1 { + return errors.New("length of data does not match required parameters") } // Define part 2 and 3 of the data array @@ -65,12 +65,12 @@ func (f *ConsumeFuzzer) Split(minCalls, maxCalls int) error { // Just a small check. It is necessary if len(commandPart) != numberOfCalls { - return errors.New("Length of commandPart does not match number of calls") + return errors.New("length of commandPart does not match number of calls") } // Check if restOfArray is divisible by numberOfCalls if !IsDivisibleBy(len(restOfArray), numberOfCalls) { - return errors.New("Length of commandPart does not match number of calls") + return errors.New("length of commandPart does not match number of calls") } f.CommandPart = commandPart f.RestOfArray = restOfArray @@ -87,75 +87,53 @@ func (f *ConsumeFuzzer) DisallowUnexportedFields() { } func (f *ConsumeFuzzer) GenerateStruct(targetStruct interface{}) error { - v := reflect.ValueOf(targetStruct) - /*if !v.CanSet() { - return errors.New("This interface cannot be set") - }*/ - e := v.Elem() - err := f.fuzzStruct(e, false) - if err != nil { - return err - } - return nil + e := reflect.ValueOf(targetStruct).Elem() + return f.fuzzStruct(e, false) } func (f *ConsumeFuzzer) setCustom(v reflect.Value) error { // First: see if we have a fuzz function for it. doCustom, ok := f.Funcs[v.Type()] if !ok { - return fmt.Errorf("Could not find a custom function") + return fmt.Errorf("could not find a custom function") } switch v.Kind() { case reflect.Ptr: if v.IsNil() { if !v.CanSet() { - return fmt.Errorf("Could not use a custom function") + return fmt.Errorf("could not use a custom function") } v.Set(reflect.New(v.Type().Elem())) } case reflect.Map: if v.IsNil() { if !v.CanSet() { - return fmt.Errorf("Could not use a custom function") + return fmt.Errorf("could not use a custom function") } v.Set(reflect.MakeMap(v.Type())) } default: - return fmt.Errorf("Could not use a custom function") + return fmt.Errorf("could not use a custom function") } verr := doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{ F: f, })}) + // check if we return an error if verr[0].IsNil() { return nil } - return fmt.Errorf("Could not use a custom function") + return fmt.Errorf("could not use a custom function") } func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error { - // We check if we should check for custom functions - if customFunctions { - if e.IsValid() { - if e.CanAddr() { - err := f.setCustom(e.Addr()) - if err == nil { - return nil - } - } - /* return f.setCustom(e) - _, ok := f.Funcs[e.Type()] - if ok { - if e.CanAddr() { - err := f.setCustom(e.Addr()) - if err == nil { - return nil - } - }*/ - //return f.setCustom(e) + if customFunctions && e.IsValid() && e.CanAddr() { + err := f.setCustom(e.Addr()) + if err == nil { + return nil } } @@ -167,24 +145,14 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error if f.fuzzUnexportedFields { v = reflect.NewAt(e.Field(i).Type(), unsafe.Pointer(e.Field(i).UnsafeAddr())).Elem() } - err := f.fuzzStruct(v, customFunctions) - if err != nil { + if err := f.fuzzStruct(v, customFunctions); err != nil { return err } } else { - /*if e.Field(i).Kind() == reflect.Struct { - //e = reflect.NewAt(e.Type(), unsafe.Pointer(e.UnsafeAddr())).Elem() - //e.Field(i).Set(reflect.New(e.Field(i).Type())) - }*/ v = e.Field(i) - //v = reflect.New(e.Field(i).Type()) - err := f.fuzzStruct(v, customFunctions) - if err != nil { + if err := f.fuzzStruct(v, customFunctions); err != nil { return err } - /*if e.Field(i).CanSet() { - e.Field(i).Set(v.Elem()) - }*/ } } case reflect.String: @@ -208,18 +176,16 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error if err != nil { return err } - var numOfElements uint32 - numOfElements = randQty % maxElements - if (uint32(len(f.data)) - f.position) < numOfElements { - numOfElements = uint32(len(f.data)) - f.position + numOfElements := randQty % maxElements + if (f.dataTotal - f.position) < numOfElements { + numOfElements = f.dataTotal - f.position } uu := reflect.MakeSlice(e.Type(), int(numOfElements), int(numOfElements)) for i := 0; i < int(numOfElements); i++ { - err := f.fuzzStruct(uu.Index(i), customFunctions) // If we have more than 10, then we can proceed with that. - if err != nil { + if err := f.fuzzStruct(uu.Index(i), customFunctions); err != nil { if i >= 10 { if e.CanSet() { e.Set(uu) @@ -284,7 +250,7 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error case reflect.Map: if e.CanSet() { e.Set(reflect.MakeMap(e.Type())) - maxElements := 50 + const maxElements = 50 randQty, err := f.GetInt() if err != nil { return err @@ -292,13 +258,11 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error numOfElements := randQty % maxElements for i := 0; i < numOfElements; i++ { key := reflect.New(e.Type().Key()).Elem() - err := f.fuzzStruct(key, customFunctions) - if err != nil { + if err := f.fuzzStruct(key, customFunctions); err != nil { return err } val := reflect.New(e.Type().Elem()).Elem() - err = f.fuzzStruct(val, customFunctions) - if err != nil { + if err = f.fuzzStruct(val, customFunctions); err != nil { return err } e.SetMapIndex(key, val) @@ -307,8 +271,7 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error case reflect.Ptr: if e.CanSet() { e.Set(reflect.New(e.Type().Elem())) - err := f.fuzzStruct(e.Elem(), customFunctions) - if err != nil { + if err := f.fuzzStruct(e.Elem(), customFunctions); err != nil { return err } return nil @@ -321,43 +284,39 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error if e.CanSet() { e.SetUint(uint64(b)) } - default: - return nil } return nil } func (f *ConsumeFuzzer) GetStringArray() (reflect.Value, error) { // The max size of the array: - max := uint32(20) + const max uint32 = 20 arraySize := f.position if arraySize > max { arraySize = max } - elemType := reflect.TypeOf("string") - stringArray := reflect.MakeSlice(reflect.SliceOf(elemType), int(arraySize), int(arraySize)) - if f.position+arraySize >= uint32(len(f.data)) { - return stringArray, errors.New("Could not make string array") + stringArray := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf("string")), int(arraySize), int(arraySize)) + if f.position+arraySize >= f.dataTotal { + return stringArray, errors.New("could not make string array") } for i := 0; i < int(arraySize); i++ { stringSize := uint32(f.data[f.position]) - - if f.position+stringSize >= uint32(len(f.data)) { + if f.position+stringSize >= f.dataTotal { return stringArray, nil } stringToAppend := string(f.data[f.position : f.position+stringSize]) strVal := reflect.ValueOf(stringToAppend) stringArray = reflect.Append(stringArray, strVal) - f.position = f.position + stringSize + f.position += stringSize } return stringArray, nil } func (f *ConsumeFuzzer) GetInt() (int, error) { - if f.position >= uint32(len(f.data)) { - return 0, errors.New("Not enough bytes to create int") + if f.position >= f.dataTotal { + return 0, errors.New("not enough bytes to create int") } returnInt := int(f.data[f.position]) f.position++ @@ -365,29 +324,23 @@ func (f *ConsumeFuzzer) GetInt() (int, error) { } func (f *ConsumeFuzzer) GetByte() (byte, error) { - if len(f.data) == 0 { - return 0x00, errors.New("Not enough bytes to get byte") - } - if f.position >= uint32(len(f.data)) { - return 0x00, errors.New("Not enough bytes to get byte") + if f.position >= f.dataTotal { + return 0x00, errors.New("not enough bytes to get byte") } returnByte := f.data[f.position] - f.position += 1 + f.position++ return returnByte, nil } func (f *ConsumeFuzzer) GetNBytes(numberOfBytes int) ([]byte, error) { - returnBytes := make([]byte, 0) - if len(f.data) == 0 { - return returnBytes, errors.New("Not enough bytes to get byte") - } - if f.position >= uint32(len(f.data)) { - return returnBytes, errors.New("Not enough bytes to get byte") + if f.position >= f.dataTotal { + return nil, errors.New("not enough bytes to get byte") } + returnBytes := make([]byte, 0, numberOfBytes) for i := 0; i < numberOfBytes; i++ { newByte, err := f.GetByte() if err != nil { - return returnBytes, err + return nil, err } returnBytes = append(returnBytes, newByte) } @@ -397,112 +350,104 @@ func (f *ConsumeFuzzer) GetNBytes(numberOfBytes int) ([]byte, error) { func (f *ConsumeFuzzer) GetUint16() (uint16, error) { u16, err := f.GetNBytes(2) if err != nil { - return uint16(0), err + return 0, err } littleEndian, err := f.GetBool() if err != nil { - return uint16(0), err + return 0, err } if littleEndian { - u16LE := binary.LittleEndian.Uint16(u16) - return u16LE, nil + return binary.LittleEndian.Uint16(u16), nil } - u16BE := binary.BigEndian.Uint16(u16) - return u16BE, nil + return binary.BigEndian.Uint16(u16), nil } func (f *ConsumeFuzzer) GetUint32() (uint32, error) { u32, err := f.GetNBytes(4) if err != nil { - return uint32(0), err + return 0, err } littleEndian, err := f.GetBool() if err != nil { - return uint32(0), err + return 0, err } if littleEndian { - u32LE := binary.LittleEndian.Uint32(u32) - return u32LE, nil + return binary.LittleEndian.Uint32(u32), nil } - u32BE := binary.BigEndian.Uint32(u32) - return u32BE, nil + return binary.BigEndian.Uint32(u32), nil } func (f *ConsumeFuzzer) GetUint64() (uint64, error) { u64, err := f.GetNBytes(8) if err != nil { - return uint64(0), err + return 0, err } littleEndian, err := f.GetBool() if err != nil { - return uint64(0), err + return 0, err } if littleEndian { - u64LE := binary.LittleEndian.Uint64(u64) - return u64LE, nil + return binary.LittleEndian.Uint64(u64), nil } - u64BE := binary.BigEndian.Uint64(u64) - return u64BE, nil + return binary.BigEndian.Uint64(u64), nil } func (f *ConsumeFuzzer) GetBytes() ([]byte, error) { - if len(f.data) == 0 || f.position >= uint32(len(f.data)) { - return nil, errors.New("Not enough bytes to create byte array") + if f.position >= f.dataTotal { + return nil, errors.New("not enough bytes to create byte array") } length, err := f.GetUint32() if err != nil { - return nil, errors.New("Not enough bytes to create byte array") + return nil, errors.New("not enough bytes to create byte array") } if f.position+length > MaxTotalLen { - return nil, errors.New("Created too large a string") + return nil, errors.New("created too large a string") } byteBegin := f.position - 1 - if byteBegin >= uint32(len(f.data)) { - return nil, errors.New("Not enough bytes to create byte array") + if byteBegin >= f.dataTotal { + return nil, errors.New("not enough bytes to create byte array") } if length == 0 { - return nil, errors.New("Zero-length is not supported") + return nil, errors.New("zero-length is not supported") } - if byteBegin+length >= uint32(len(f.data)) { - return nil, errors.New("Not enough bytes to create byte array") + if byteBegin+length >= f.dataTotal { + return nil, errors.New("not enough bytes to create byte array") } if byteBegin+length < byteBegin { - return nil, errors.New("Nunmbers overflow. Returning") + return nil, errors.New("numbers overflow") } - b := f.data[byteBegin : byteBegin+length] f.position = byteBegin + length - return b, nil + return f.data[byteBegin:f.position], nil } func (f *ConsumeFuzzer) GetString() (string, error) { - if f.position >= uint32(len(f.data)) { - return "nil", errors.New("Not enough bytes to create string") + if f.position >= f.dataTotal { + return "nil", errors.New("not enough bytes to create string") } length, err := f.GetUint32() if err != nil { - return "nil", errors.New("Not enough bytes to create string") + return "nil", errors.New("not enough bytes to create string") } if f.position > MaxTotalLen { - return "nil", errors.New("Created too large a string") + return "nil", errors.New("created too large a string") } byteBegin := f.position - 1 - if byteBegin >= uint32(len(f.data)) { - return "nil", errors.New("Not enough bytes to create string") + if byteBegin >= f.dataTotal { + return "nil", errors.New("not enough bytes to create string") } - if byteBegin+length > uint32(len(f.data)) { - return "nil", errors.New("Not enough bytes to create string") + if byteBegin+length > f.dataTotal { + return "nil", errors.New("not enough bytes to create string") } if byteBegin > byteBegin+length { - return "nil", errors.New("Numbers overflow. Returning") + return "nil", errors.New("numbers overflow") } - str := string(f.data[byteBegin : byteBegin+length]) f.position = byteBegin + length - return str, nil + return string(f.data[byteBegin:f.position]), nil } func (f *ConsumeFuzzer) GetBool() (bool, error) { - if f.position >= uint32(len(f.data)) { - return false, errors.New("Not enough bytes to create bool") + if f.position >= f.dataTotal { + return false, errors.New("not enough bytes to create bool") } if IsDivisibleBy(int(f.data[f.position]), 2) { f.position++ @@ -514,20 +459,13 @@ func (f *ConsumeFuzzer) GetBool() (bool, error) { } func (f *ConsumeFuzzer) FuzzMap(m interface{}) error { - err := f.GenerateStruct(m) - if err != nil { - return err - } - return nil + return f.GenerateStruct(m) } func returnTarBytes(buf []byte) ([]byte, error) { - reader := bytes.NewReader(buf) - tr := tar.NewReader(reader) - // Count files var fileCounter int - fileCounter = 0 + tr := tar.NewReader(bytes.NewReader(buf)) for { _, err := tr.Next() if err == io.EOF { @@ -541,7 +479,7 @@ func returnTarBytes(buf []byte) ([]byte, error) { if fileCounter > 4 { return buf, nil } - return nil, fmt.Errorf("Not enough files were created\n") + return nil, fmt.Errorf("not enough files were created\n") } func setTarHeaderFormat(hdr *tar.Header, f *ConsumeFuzzer) error { @@ -609,94 +547,77 @@ func setTarHeaderTypeflag(hdr *tar.Header, f *ConsumeFuzzer) error { } func (f *ConsumeFuzzer) createTarFileBody() ([]byte, error) { - if len(f.data) == 0 || f.position >= uint32(len(f.data)) { - return nil, errors.New("Not enough bytes to create byte array") - } length, err := f.GetUint32() if err != nil { - return nil, errors.New("Not enough bytes to create byte array") + return nil, errors.New("not enough bytes to create byte array") } // A bit of optimization to attempt to create a file body // when we don't have as many bytes left as "length" - remainingBytes := (uint32(len(f.data)) - f.position) - totalDataLen := uint32(len(f.data)) - if uint32(len(f.data))-f.position < 50 { - if remainingBytes == 0 { - return nil, errors.New("Created too large a string") - } + remainingBytes := f.dataTotal - f.position + if remainingBytes == 0 { + return nil, errors.New("created too large a string") + } + if remainingBytes < 50 { length = length % remainingBytes - } else if len(f.data) < 500 { - if totalDataLen == 0 { - return nil, errors.New("Created too large a string") - } - length = length % totalDataLen + } else if f.dataTotal < 500 { + length = length % f.dataTotal } if f.position+length > MaxTotalLen { - return nil, errors.New("Created too large a string") + return nil, errors.New("created too large a string") } byteBegin := f.position - 1 - if byteBegin >= uint32(len(f.data)) { - return nil, errors.New("Not enough bytes to create byte array") + if byteBegin >= f.dataTotal { + return nil, errors.New("not enough bytes to create byte array") } if length == 0 { - return nil, errors.New("Zero-length is not supported") + return nil, errors.New("zero-length is not supported") } - if byteBegin+length >= uint32(len(f.data)) { - return nil, errors.New("Not enough bytes to create byte array") + if byteBegin+length >= f.dataTotal { + return nil, errors.New("not enough bytes to create byte array") } if byteBegin+length < byteBegin { - return nil, errors.New("Nunmbers overflow. Returning") + return nil, errors.New("numbers overflow") } - filebody := f.data[byteBegin : byteBegin+length] f.position = byteBegin + length - return filebody, nil - + return f.data[byteBegin:f.position], nil } -// Is similar to GetString(), but creates string based on the length -// of the length of f.data to increase the likelihood of not overflowing -// f.data +// getTarFileName is similar to GetString(), but creates string based +// on the length of f.data to reduce the likelihood of overflowing +// f.data. func (f *ConsumeFuzzer) getTarFilename() (string, error) { - if f.position >= uint32(len(f.data)) { - return "nil", errors.New("Not enough bytes to create string") - } length, err := f.GetUint32() if err != nil { - return "nil", errors.New("Not enough bytes to create string") + return "nil", errors.New("not enough bytes to create string") } // A bit of optimization to attempt to create a file name // when we don't have as many bytes left as "length" - remainingBytes := (uint32(len(f.data)) - f.position) - totalDataLen := uint32(len(f.data)) - if uint32(len(f.data))-f.position < 50 { - if remainingBytes == 0 { - return "nil", errors.New("Created too large a string") - } + remainingBytes := f.dataTotal - f.position + if remainingBytes == 0 { + return "nil", errors.New("created too large a string") + } + if remainingBytes < 50 { length = length % remainingBytes - } else if len(f.data) < 500 { - if totalDataLen == 0 { - return "nil", errors.New("Created too large a string") - } - length = length % totalDataLen + } else if f.dataTotal < 500 { + length = length % f.dataTotal } if f.position > MaxTotalLen { - return "nil", errors.New("Created too large a string") + return "nil", errors.New("created too large a string") } byteBegin := f.position - 1 - if byteBegin >= uint32(len(f.data)) { - return "nil", errors.New("Not enough bytes to create string") + if byteBegin >= f.dataTotal { + return "nil", errors.New("not enough bytes to create string") } - if byteBegin+length > uint32(len(f.data)) { - return "nil", errors.New("Not enough bytes to create string") + if byteBegin+length > f.dataTotal { + return "nil", errors.New("not enough bytes to create string") } if byteBegin > byteBegin+length { - return "nil", errors.New("Numbers overflow. Returning") + return "nil", errors.New("numbers overflow") } - str := string(f.data[byteBegin : byteBegin+length]) f.position = byteBegin + length - return str, nil + return string(f.data[byteBegin:f.position]), nil } // TarBytes returns valid bytes for a tar archive @@ -710,7 +631,7 @@ func (f *ConsumeFuzzer) TarBytes() ([]byte, error) { tw := tar.NewWriter(&buf) defer tw.Close() - maxNoOfFiles := 1000 + const maxNoOfFiles = 1000 for i := 0; i < numberOfFiles%maxNoOfFiles; i++ { filename, err := f.getTarFilename() if err != nil { @@ -720,34 +641,27 @@ func (f *ConsumeFuzzer) TarBytes() ([]byte, error) { if err != nil { return returnTarBytes(buf.Bytes()) } - hdr := &tar.Header{} - - err = setTarHeaderTypeflag(hdr, f) - if err != nil { - return returnTarBytes(buf.Bytes()) - } - sec, err := f.GetInt() if err != nil { return returnTarBytes(buf.Bytes()) } - nsec, err := f.GetInt() if err != nil { return returnTarBytes(buf.Bytes()) } - hdr.ModTime = time.Unix(int64(sec), int64(nsec)) - - hdr.Name = filename - hdr.Size = int64(len(filebody)) - hdr.Mode = 0600 - - err = setTarHeaderFormat(hdr, f) - if err != nil { + hdr := &tar.Header{ + Name: filename, + Size: int64(len(filebody)), + Mode: 0o600, + ModTime: time.Unix(int64(sec), int64(nsec)), + } + if err := setTarHeaderTypeflag(hdr, f); err != nil { + return returnTarBytes(buf.Bytes()) + } + if err := setTarHeaderFormat(hdr, f); err != nil { return returnTarBytes(buf.Bytes()) } - if err := tw.WriteHeader(hdr); err != nil { return returnTarBytes(buf.Bytes()) } @@ -758,13 +672,11 @@ func (f *ConsumeFuzzer) TarBytes() ([]byte, error) { return returnTarBytes(buf.Bytes()) } -// Creates pseudo-random files in rootDir. -// Will create subdirs and place the files there. +// CreateFiles creates pseudo-random files in rootDir. +// It creates subdirs and places the files there. // It is the callers responsibility to ensure that // rootDir exists. func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { - var noOfCreatedFiles int - noOfCreatedFiles = 0 numberOfFiles, err := f.GetInt() if err != nil { return err @@ -774,40 +686,35 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { return errors.New("maxNumberOfFiles is nil") } + var noOfCreatedFiles int for i := 0; i < maxNumberOfFiles; i++ { // The file to create: fileName, err := f.GetString() if err != nil { if noOfCreatedFiles > 0 { - // If files have been created, we don't return - // an error + // If files have been created, we don't return an error. break } else { - return errors.New("Could not get fileName") + return errors.New("could not get fileName") } } - var fullFilePath string - fullFilePath, err = securejoin.SecureJoin(rootDir, fileName) + fullFilePath, err := securejoin.SecureJoin(rootDir, fileName) if err != nil { return err } // Find the subdirectory of the file - subDir := filepath.Dir(fileName) - if subDir != "" && subDir != "." { - // create the dir first - - // Avoid going outside the root dir + if subDir := filepath.Dir(fileName); subDir != "" && subDir != "." { + // create the dir first; avoid going outside the root dir if strings.Contains(subDir, "../") || (len(subDir) > 0 && subDir[0] == 47) || strings.Contains(subDir, "\\") { continue } - dirPath := filepath.Join(rootDir, subDir) dirPath, err := securejoin.SecureJoin(rootDir, subDir) if err != nil { continue } if _, err := os.Stat(dirPath); os.IsNotExist(err) { - err2 := os.MkdirAll(dirPath, 0777) + err2 := os.MkdirAll(dirPath, 0o777) if err2 != nil { continue } @@ -823,7 +730,7 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { if noOfCreatedFiles > 0 { break } else { - return errors.New("Could not create the symlink") + return errors.New("could not create the symlink") } } if createSymlink { @@ -831,7 +738,10 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { if err != nil { return err } - os.Symlink(symlinkTarget, fullFilePath) + err = os.Symlink(symlinkTarget, fullFilePath) + if err != nil { + return err + } // stop loop here, since a symlink needs no further action noOfCreatedFiles++ continue @@ -842,43 +752,35 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { if noOfCreatedFiles > 0 { break } else { - return errors.New("Could not create the file") + return errors.New("could not create the file") } } - createdFile, err := os.Create(fullFilePath) + err = os.WriteFile(fullFilePath, fileContents, 0o666) if err != nil { - createdFile.Close() continue } - _, err = createdFile.Write(fileContents) - if err != nil { - createdFile.Close() - continue - } - createdFile.Close() noOfCreatedFiles++ } } return nil } -// Returns a string that can only consists of characters that are -// included in possibleChars. Will return an error if the created -// string does not have the specified length +// GetStringFrom returns a string that can only consist of characters +// included in possibleChars. It returns an error if the created string +// does not have the specified length. func (f *ConsumeFuzzer) GetStringFrom(possibleChars string, length int) (string, error) { - returnString := "" - if (uint32(len(f.data)) - f.position) < uint32(length) { - return returnString, errors.New("Not enough bytes to create a string") + if (f.dataTotal - f.position) < uint32(length) { + return "", errors.New("not enough bytes to create a string") } + output := make([]byte, 0, length) for i := 0; i < length; i++ { charIndex, err := f.GetInt() if err != nil { - return returnString, err + return string(output), err } - charToAdd := string(possibleChars[charIndex%len(possibleChars)]) - returnString = fmt.Sprintf(returnString + charToAdd) + output = append(output, possibleChars[charIndex%len(possibleChars)]) } - return returnString, nil + return string(output), nil } func (f *ConsumeFuzzer) GetRune() ([]rune, error) { @@ -892,11 +794,11 @@ func (f *ConsumeFuzzer) GetRune() ([]rune, error) { func (f *ConsumeFuzzer) GetFloat32() (float32, error) { u32, err := f.GetNBytes(4) if err != nil { - return float32(0.0), err + return 0, err } littleEndian, err := f.GetBool() if err != nil { - return float32(0.0), err + return 0, err } if littleEndian { u32LE := binary.LittleEndian.Uint32(u32) @@ -909,11 +811,11 @@ func (f *ConsumeFuzzer) GetFloat32() (float32, error) { func (f *ConsumeFuzzer) GetFloat64() (float64, error) { u64, err := f.GetNBytes(8) if err != nil { - return float64(0.0), err + return 0, err } littleEndian, err := f.GetBool() if err != nil { - return float64(0.0), err + return 0, err } if littleEndian { u64LE := binary.LittleEndian.Uint64(u64) @@ -924,9 +826,5 @@ func (f *ConsumeFuzzer) GetFloat64() (float64, error) { } func (f *ConsumeFuzzer) CreateSlice(targetSlice interface{}) error { - err := f.GenerateStruct(targetSlice) - if err != nil { - return err - } - return nil + return f.GenerateStruct(targetSlice) } diff --git a/vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go b/vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go index 93622d47c..40273c13a 100644 --- a/vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go +++ b/vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go @@ -35,23 +35,14 @@ func (f *ConsumeFuzzer) AddFuncs(fuzzFuncs []interface{}) { } func (f *ConsumeFuzzer) GenerateWithCustom(targetStruct interface{}) error { - v := reflect.ValueOf(targetStruct) - e := v.Elem() + e := reflect.ValueOf(targetStruct).Elem() return f.fuzzStruct(e, true) } func (c Continue) GenerateStruct(targetStruct interface{}) error { - err := c.F.GenerateStruct(targetStruct) - if err != nil { - return err - } - return nil + return c.F.GenerateStruct(targetStruct) } func (c Continue) GenerateStructWithCustom(targetStruct interface{}) error { - err := c.F.GenerateWithCustom(targetStruct) - if err != nil { - return err - } - return nil + return c.F.GenerateWithCustom(targetStruct) } diff --git a/vendor/github.com/AdaLogics/go-fuzz-headers/sql.go b/vendor/github.com/AdaLogics/go-fuzz-headers/sql.go index b5d16904f..9290aac3a 100644 --- a/vendor/github.com/AdaLogics/go-fuzz-headers/sql.go +++ b/vendor/github.com/AdaLogics/go-fuzz-headers/sql.go @@ -16,7 +16,7 @@ func getKeyword(f *ConsumeFuzzer) (string, error) { return k, nil } } - return keywords[0], fmt.Errorf("Could not get a kw") + return keywords[0], fmt.Errorf("could not get a kw") } // Simple utility function to check if a string @@ -101,7 +101,8 @@ var keywords = []string{ "vitess_migration", "vitess_migrations", "vitess_replication_status", "vitess_shards", "vitess_tablets", "vschema", "warnings", "when", "where", "while", "window", "with", "without", "work", "write", "xor", - "year", "year_month", "zerofill"} + "year", "year_month", "zerofill", +} // Keywords that could get an additional keyword var needCustomString = []string{ @@ -131,11 +132,15 @@ var alterTableTokens = [][]string{ } var alterTokens = [][]string{ - {"DATABASE", "SCHEMA", "DEFINER = ", "EVENT", "FUNCTION", "INSTANCE", - "LOGFILE GROUP", "PROCEDURE", "SERVER"}, + { + "DATABASE", "SCHEMA", "DEFINER = ", "EVENT", "FUNCTION", "INSTANCE", + "LOGFILE GROUP", "PROCEDURE", "SERVER", + }, {"CUSTOM_FUZZ_STRING"}, - {"ON SCHEDULE", "ON COMPLETION PRESERVE", "ON COMPLETION NOT PRESERVE", - "ADD UNDOFILE", "OPTIONS"}, + { + "ON SCHEDULE", "ON COMPLETION PRESERVE", "ON COMPLETION NOT PRESERVE", + "ADD UNDOFILE", "OPTIONS", + }, {"RENAME TO", "INITIAL_SIZE = "}, {"ENABLE", "DISABLE", "DISABLE ON SLAVE", "ENGINE"}, {"COMMENT"}, @@ -150,9 +155,11 @@ var setTokens = [][]string{ var dropTokens = [][]string{ {"TEMPORARY", "UNDO"}, - {"DATABASE", "SCHEMA", "EVENT", "INDEX", "LOGFILE GROUP", + { + "DATABASE", "SCHEMA", "EVENT", "INDEX", "LOGFILE GROUP", "PROCEDURE", "FUNCTION", "SERVER", "SPATIAL REFERENCE SYSTEM", - "TABLE", "TABLESPACE", "TRIGGER", "VIEW"}, + "TABLE", "TABLESPACE", "TRIGGER", "VIEW", + }, {"IF EXISTS"}, {"CUSTOM_FUZZ_STRING"}, {"ON", "ENGINE = ", "RESTRICT", "CASCADE"}, @@ -172,15 +179,21 @@ var truncateTokens = [][]string{ var createTokens = [][]string{ {"OR REPLACE", "TEMPORARY", "UNDO"}, // For create spatial reference system - {"UNIQUE", "FULLTEXT", "SPATIAL", "ALGORITHM = UNDEFINED", "ALGORITHM = MERGE", - "ALGORITHM = TEMPTABLE"}, - {"DATABASE", "SCHEMA", "EVENT", "FUNCTION", "INDEX", "LOGFILE GROUP", + { + "UNIQUE", "FULLTEXT", "SPATIAL", "ALGORITHM = UNDEFINED", "ALGORITHM = MERGE", + "ALGORITHM = TEMPTABLE", + }, + { + "DATABASE", "SCHEMA", "EVENT", "FUNCTION", "INDEX", "LOGFILE GROUP", "PROCEDURE", "SERVER", "SPATIAL REFERENCE SYSTEM", "TABLE", "TABLESPACE", - "TRIGGER", "VIEW"}, + "TRIGGER", "VIEW", + }, {"IF NOT EXISTS"}, {"CUSTOM_FUZZ_STRING"}, } +/* +// For future use. var updateTokens = [][]string{ {"LOW_PRIORITY"}, {"IGNORE"}, @@ -189,6 +202,8 @@ var updateTokens = [][]string{ {"ORDER BY"}, {"LIMIT"}, } +*/ + var replaceTokens = [][]string{ {"LOW_PRIORITY", "DELAYED"}, {"INTO"}, @@ -196,6 +211,7 @@ var replaceTokens = [][]string{ {"CUSTOM_FUZZ_STRING"}, {"VALUES", "VALUE"}, } + var loadTokens = [][]string{ {"DATA"}, {"LOW_PRIORITY", "CONCURRENT", "LOCAL"}, @@ -271,22 +287,24 @@ var alter_table_options = []string{ "COMPACT", "SECONDARY_ENGINE_ATTRIBUTE", "STATS_AUTO_RECALC", "STATS_PERSISTENT", "STATS_SAMPLE_PAGES", "ZLIB", "LZ4", "ENGINE_ATTRIBUTE", "KEY_BLOCK_SIZE", "MAX_ROWS", "MIN_ROWS", "PACK_KEYS", "PASSWORD", "COMPRESSION", "CONNECTION", "DIRECTORY", - "DELAY_KEY_WRITE", "ENCRYPTION", "STORAGE", "DISK", "MEMORY", "UNION"} + "DELAY_KEY_WRITE", "ENCRYPTION", "STORAGE", "DISK", "MEMORY", "UNION", +} // Creates an 'alter table' statement. 'alter table' is an exception // in that it has its own function. The majority of statements // are created by 'createStmt()'. func createAlterTableStmt(f *ConsumeFuzzer) (string, error) { - var stmt strings.Builder - stmt.WriteString("ALTER TABLE ") maxArgs, err := f.GetInt() if err != nil { return "", err } maxArgs = maxArgs % 30 if maxArgs == 0 { - return "", fmt.Errorf("Could not create alter table stmt") + return "", fmt.Errorf("could not create alter table stmt") } + + var stmt strings.Builder + stmt.WriteString("ALTER TABLE ") for i := 0; i < maxArgs; i++ { // Calculate if we get existing token or custom string tokenType, err := f.GetInt() @@ -298,13 +316,13 @@ func createAlterTableStmt(f *ConsumeFuzzer) (string, error) { if err != nil { return "", err } - stmt.WriteString(fmt.Sprintf(" %s", customString)) + stmt.WriteString(" " + customString) } else { tokenIndex, err := f.GetInt() if err != nil { return "", err } - stmt.WriteString(fmt.Sprintf(" %s", alter_table_options[tokenIndex%len(alter_table_options)])) + stmt.WriteString(" " + alter_table_options[tokenIndex%len(alter_table_options)]) } } return stmt.String(), nil @@ -316,7 +334,7 @@ func chooseToken(tokens []string, f *ConsumeFuzzer) (string, error) { return "", err } var token strings.Builder - token.WriteString(fmt.Sprintf(" %s", tokens[index%len(tokens)])) + token.WriteString(tokens[index%len(tokens)]) if token.String() == "CUSTOM_FUZZ_STRING" { customFuzzString, err := f.GetString() if err != nil { @@ -331,7 +349,7 @@ func chooseToken(tokens []string, f *ConsumeFuzzer) (string, error) { if err != nil { return "", err } - token.WriteString(fmt.Sprintf(" %s", customFuzzString)) + token.WriteString(" " + customFuzzString) } return token.String(), nil } @@ -398,21 +416,19 @@ func createStmt(f *ConsumeFuzzer) (string, error) { if err != nil { return "", err } - query.WriteString(fmt.Sprintf(" %s", queryArgs)) + query.WriteString(" " + queryArgs) return query.String(), nil } // Creates the arguments of a statements. In a select statement // that would be everything after "select". func createStmtArgs(tokenslice [][]string, f *ConsumeFuzzer) (string, error) { - var query strings.Builder - var token strings.Builder + var query, token strings.Builder // We go through the tokens in the tokenslice, // create the respective token and add it to // "query" for _, tokens := range tokenslice { - // For extra randomization, the fuzzer can // choose to not include this token. includeThisToken, err := f.GetBool() @@ -429,7 +445,7 @@ func createStmtArgs(tokenslice [][]string, f *ConsumeFuzzer) (string, error) { if err != nil { return "", err } - query.WriteString(fmt.Sprintf(" %s", chosenToken)) + query.WriteString(" " + chosenToken) } else { token.WriteString(tokens[0]) @@ -440,7 +456,7 @@ func createStmtArgs(tokenslice [][]string, f *ConsumeFuzzer) (string, error) { if err != nil { return "", err } - query.WriteString(fmt.Sprintf(" %s", customFuzzString)) + query.WriteString(" " + customFuzzString) continue } @@ -470,7 +486,7 @@ func createQuery(f *ConsumeFuzzer) (string, error) { } maxLen := queryLen % 60 if maxLen == 0 { - return "", fmt.Errorf("Could not create a query") + return "", fmt.Errorf("could not create a query") } var query strings.Builder for i := 0; i < maxLen; i++ { @@ -484,25 +500,27 @@ func createQuery(f *ConsumeFuzzer) (string, error) { if err != nil { return "", err } - query.WriteString(fmt.Sprintf(" %s", keyword)) + query.WriteString(" " + keyword) } else { customString, err := f.GetString() if err != nil { return "", err } - query.WriteString(fmt.Sprintf(" %s", customString)) + query.WriteString(" " + customString) } } if query.String() == "" { - return "", fmt.Errorf("Could not create a query") + return "", fmt.Errorf("could not create a query") } return query.String(), nil } -// This is the API that users will interact with. +// GetSQLString is the API that users interact with. +// // Usage: -// f := NewConsumer(data) -// sqlString, err := f.GetSQLString() +// +// f := NewConsumer(data) +// sqlString, err := f.GetSQLString() func (f *ConsumeFuzzer) GetSQLString() (string, error) { var query string veryStructured, err := f.GetBool() diff --git a/vendor/modules.txt b/vendor/modules.txt index be8add0de..b8b9fab27 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,7 +1,7 @@ # cloud.google.com/go/compute/metadata v0.2.1 ## explicit; go 1.19 -# github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8 -## explicit; go 1.13 +# github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72 +## explicit; go 1.18 github.com/AdaLogics/go-fuzz-headers # github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20220912195655-e1f97a00006b ## explicit; go 1.18