THRIFT-2500 sending random data crashes thrift(golang) service

Client: Go
Patch: Aleksey Pesternikov

This closes #117

commit 1bb25c4a48845e112847ca8293402f0294d8f597
 Author: Aleksey Pesternikov <ap@alekseys-mbp.att.net>
 Date: 2014-05-02T21:40:59Z

recover from panic in processor

commit 8d1427a2c3c183d499442dc1f0437292e6641ac3
 Author: Aleksey Pesternikov <ap@alekseys-mbp.att.net>
 Date: 2014-05-02T21:41:52Z

some sanity checks in binary protocol

commit 666cc87a51f86ca5940225c36716bbad467c6e73
 Author: Aleksey Pesternikov <ap@alekseys-mbp.att.net>
 Date: 2014-05-02T21:53:59Z

some sanity checks in compact protocol
This commit is contained in:
Jens Geyer 2014-05-17 01:07:28 +02:00
parent b7cb9457dc
commit 91cfb9901e
4 changed files with 57 additions and 9 deletions

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"io" "io"
"math" "math"
@ -301,6 +302,8 @@ func (p *TBinaryProtocol) ReadFieldEnd() error {
return nil return nil
} }
var invalidDataLength = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Invalid data length"))
func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) { func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) {
k, e := p.ReadByte() k, e := p.ReadByte()
if e != nil { if e != nil {
@ -315,11 +318,15 @@ func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err erro
} }
vType = TType(v) vType = TType(v)
size32, e := p.ReadI32() size32, e := p.ReadI32()
size = int(size32)
if e != nil { if e != nil {
err = NewTProtocolException(e) err = NewTProtocolException(e)
return return
} }
if size32 < 0 {
err = invalidDataLength
return
}
size = int(size32)
return kType, vType, size, nil return kType, vType, size, nil
} }
@ -335,12 +342,17 @@ func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err error)
} }
elemType = TType(b) elemType = TType(b)
size32, e := p.ReadI32() size32, e := p.ReadI32()
size = int(size32)
if e != nil { if e != nil {
err = NewTProtocolException(e) err = NewTProtocolException(e)
return return
} }
return elemType, size, nil if size32 < 0 {
err = invalidDataLength
return
}
size = int(size32)
return
} }
func (p *TBinaryProtocol) ReadListEnd() error { func (p *TBinaryProtocol) ReadListEnd() error {
@ -355,11 +367,15 @@ func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err error) {
} }
elemType = TType(b) elemType = TType(b)
size32, e := p.ReadI32() size32, e := p.ReadI32()
size = int(size32)
if e != nil { if e != nil {
err = NewTProtocolException(e) err = NewTProtocolException(e)
return return
} }
if size32 < 0 {
err = invalidDataLength
return
}
size = int(size32)
return elemType, size, nil return elemType, size, nil
} }
@ -413,6 +429,11 @@ func (p *TBinaryProtocol) ReadString() (value string, err error) {
if e != nil { if e != nil {
return "", e return "", e
} }
if size < 0 {
err = invalidDataLength
return
}
return p.readStringBody(int(size)) return p.readStringBody(int(size))
} }
@ -421,6 +442,10 @@ func (p *TBinaryProtocol) ReadBinary() ([]byte, error) {
if e != nil { if e != nil {
return nil, e return nil, e
} }
if size < 0 {
return nil, invalidDataLength
}
isize := int(size) isize := int(size)
buf := make([]byte, isize) buf := make([]byte, isize)
_, err := io.ReadFull(p.trans, buf) _, err := io.ReadFull(p.trans, buf)

View File

@ -421,11 +421,16 @@ func (p *TCompactProtocol) ReadFieldEnd() error { return nil }
// "correct" types. // "correct" types.
func (p *TCompactProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err error) { func (p *TCompactProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err error) {
size32, e := p.readVarint32() size32, e := p.readVarint32()
size = int(size32)
if e != nil { if e != nil {
err = NewTProtocolException(e) err = NewTProtocolException(e)
return return
} }
if size32 < 0 {
err = invalidDataLength
return
}
size = int(size32)
keyAndValueType := byte(STOP) keyAndValueType := byte(STOP)
if size != 0 { if size != 0 {
keyAndValueType, err = p.ReadByte() keyAndValueType, err = p.ReadByte()
@ -456,6 +461,10 @@ func (p *TCompactProtocol) ReadListBegin() (elemType TType, size int, err error)
err = NewTProtocolException(e) err = NewTProtocolException(e)
return return
} }
if size2 < 0 {
err = invalidDataLength
return
}
size = int(size2) size = int(size2)
} }
elemType, e := p.getTType(tCompactType(size_and_type)) elemType, e := p.getTType(tCompactType(size_and_type))
@ -541,6 +550,10 @@ func (p *TCompactProtocol) ReadString() (value string, err error) {
if e != nil { if e != nil {
return "", NewTProtocolException(e) return "", NewTProtocolException(e)
} }
if length < 0 {
return "", invalidDataLength
}
if length == 0 { if length == 0 {
return "", nil return "", nil
} }
@ -561,7 +574,10 @@ func (p *TCompactProtocol) ReadBinary() (value []byte, err error) {
return nil, NewTProtocolException(e) return nil, NewTProtocolException(e)
} }
if length == 0 { if length == 0 {
return nil, nil //nil == empty slice return []byte{}, nil
}
if length < 0 {
return nil, invalidDataLength
} }
buf := make([]byte, length) buf := make([]byte, length)

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"log" "log"
"runtime/debug"
) )
// Simple, non-concurrent server for testing. // Simple, non-concurrent server for testing.
@ -131,7 +132,7 @@ func (p *TSimpleServer) AcceptLoop() error {
} }
if client != nil { if client != nil {
go func() { go func() {
if err := p.processRequest(client); err != nil { if err := p.processRequests(client); err != nil {
log.Println("error processing request:", err) log.Println("error processing request:", err)
} }
}() }()
@ -154,12 +155,17 @@ func (p *TSimpleServer) Stop() error {
return nil return nil
} }
func (p *TSimpleServer) processRequest(client TTransport) error { func (p *TSimpleServer) processRequests(client TTransport) error {
processor := p.processorFactory.GetProcessor(client) processor := p.processorFactory.GetProcessor(client)
inputTransport := p.inputTransportFactory.GetTransport(client) inputTransport := p.inputTransportFactory.GetTransport(client)
outputTransport := p.outputTransportFactory.GetTransport(client) outputTransport := p.outputTransportFactory.GetTransport(client)
inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport) inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport)
outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport) outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport)
defer func() {
if e := recover(); e != nil {
log.Printf("panic in processor: %s: %s", e, debug.Stack())
}
}()
if inputTransport != nil { if inputTransport != nil {
defer inputTransport.Close() defer inputTransport.Close()
} }
@ -171,6 +177,7 @@ func (p *TSimpleServer) processRequest(client TTransport) error {
if err, ok := err.(TTransportException); ok && err.TypeId() == END_OF_FILE { if err, ok := err.(TTransportException); ok && err.TypeId() == END_OF_FILE {
return nil return nil
} else if err != nil { } else if err != nil {
log.Printf("error processing request: %s", err)
return err return err
} }
if !ok { if !ok {

View File

@ -23,8 +23,8 @@
package common package common
import ( import (
thrifttest "gen/thrifttest"
gomock "code.google.com/p/gomock/gomock" gomock "code.google.com/p/gomock/gomock"
thrifttest "gen/thrifttest"
) )
// Mock of ThriftTest interface // Mock of ThriftTest interface