Skip to content

Encoder cannot handle self-referenced structures #49

@navytux

Description

@navytux

e.g. found via fuzzing (#47):

"(\x88\x88l2a22aa."

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0x51e8c6, 0xe)
        /tmp/go-fuzz-build697921479/goroot/src/runtime/panic.go:608 +0x72
runtime.newstack()
        /tmp/go-fuzz-build697921479/goroot/src/runtime/stack.go:1008 +0x729
runtime.morestack()
        /tmp/go-fuzz-build697921479/goroot/src/runtime/asm_amd64.s:429 +0x8f

goroutine 1 [running]:
runtime.mallocgc(0x8, 0x0, 0x0, 0x0)
        /tmp/go-fuzz-build697921479/goroot/src/runtime/malloc.go:773 +0x9ab fp=0xc023a34390 sp=0xc023a34388 pc=0x40b27b
runtime.rawbyteslice(0x4, 0x0, 0x0, 0x0)
        /tmp/go-fuzz-build697921479/goroot/src/runtime/string.go:271 +0xa0 fp=0xc023a343d0 sp=0xc023a34390 pc=0x43fd10
runtime.stringtoslicebyte(0x0, 0x51d353, 0x4, 0x8, 0xc0004c9b30, 0x0)
        /tmp/go-fuzz-build697921479/goroot/src/runtime/string.go:160 +0xb5 fp=0xc023a34418 sp=0xc023a343d0 pc=0x43f705
github.com/kisielk/og-rek.(*Encoder).emits(0xc043a33eb8, 0x51d353, 0x4, 0xc023a34490, 0x4924aa)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:90 +0x5a fp=0xc023a34458 sp=0xc023a34418 pc=0x4d4efa
github.com/kisielk/og-rek.(*Encoder).encodeBool(0xc043a33eb8, 0x5da901, 0x81, 0x4f7101)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:254 +0x19a fp=0xc023a344a0 sp=0xc023a34458 pc=0x4d66ba
github.com/kisielk/og-rek.(*Encoder).encode(0xc043a33eb8, 0x4f7160, 0x5da9a1, 0x81, 0x5da9a1, 0x81)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:109 +0x1ff fp=0xc023a344f8 sp=0xc023a344a0 pc=0x4d529f
github.com/kisielk/og-rek.(*Encoder).encode(0xc043a33eb8, 0x4ff000, 0xc0001329c0, 0x194, 0x4ff000, 0xc0001329c0)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:137 +0xa13 fp=0xc023a34550 sp=0xc023a344f8 pc=0x4d5ab3
github.com/kisielk/og-rek.(*Encoder).encodeArray(0xc043a33eb8, 0x4f5e80, 0xc0001329e0, 0x97, 0xc0001329e0, 0x4f5e80)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:232 +0x1ee fp=0xc023a345a8 sp=0xc023a34550 pc=0x4d639e
github.com/kisielk/og-rek.(*Encoder).encode(0xc043a33eb8, 0x4f5e80, 0xc0001329e0, 0x97, 0xc0001329e0, 0x97)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:122 +0x45e fp=0xc023a34600 sp=0xc023a345a8 pc=0x4d54fe
github.com/kisielk/og-rek.(*Encoder).encode(0xc043a33eb8, 0x4ff000, 0xc0001245a0, 0x194, 0x4ff000, 0xc0001245a0)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:137 +0xa13 fp=0xc023a34658 sp=0xc023a34600 pc=0x4d5ab3
github.com/kisielk/og-rek.(*Encoder).encodeArray(0xc043a33eb8, 0x4f5e80, 0xc000132a20, 0x97, 0xc000132a20, 0x4f5e80)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:232 +0x1ee fp=0xc023a346b0 sp=0xc023a34658 pc=0x4d639e
github.com/kisielk/og-rek.(*Encoder).encode(0xc043a33eb8, 0x4f5e80, 0xc000132a20, 0x97, 0xc000132a20, 0x97)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:122 +0x45e fp=0xc023a34708 sp=0xc023a346b0 pc=0x4d54fe
github.com/kisielk/og-rek.(*Encoder).encode(0xc043a33eb8, 0x4ff000, 0xc0001245b0, 0x194, 0x4ff000, 0xc0001245b0)
        /tmp/go-fuzz-build697921479/gopath/src/github.com/kisielk/og-rek/encode.go:137 +0xa13 fp=0xc023a34760 sp=0xc023a34708 pc=0x4d5ab3
...

It decodes self-referencing object on which the Encoder infinitely recurses (see ^^^):

In [5]: pickle.loads(s)
Out[5]: [True, True, [...], [...], [...]]

The pickle itself with details:

In [4]: dis(s)
    0: (    MARK
    1: \x88     NEWTRUE
    2: \x88     NEWTRUE
    3: l        LIST       (MARK at 0)
    4: 2    DUP
    5: a    APPEND
    6: 2    DUP
    7: 2    DUP
    8: a    APPEND
    9: a    APPEND
   10: .    STOP
highest protocol among opcodes = 2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions