go-yara: Segfault with YARA 4.1.0 RC2

Is this compatible with YARA 4.1.0? When trying to build this with that version in Debian unstable, I get test failures due to segfaults on amd64:

github.com/hillu/go-yara
   dh_auto_test -O--buildsystem=golang
	cd obj-x86_64-linux-gnu && go test -vet=off -v -p 6 github.com/hillu/go-yara
=== RUN   TestBasic
    cbpool_test.go:25: Get: Got expected panic: Attempt to get nonexistent value from pool
    cbpool_test.go:43: Delete: Got expected panic: Attempt to delete nonexistent value from pool
    cbpool_test.go:57: full pool: Got expected panic: cbPool storage exhausted
--- PASS: TestBasic (0.00s)
=== RUN   TestCompiler
    compiler_test.go:21: expected error: syntax error
--- PASS: TestCompiler (0.00s)
=== RUN   TestPanic
    compiler_test.go:31: Everything ok, MustCompile panicked: syntax error
--- PASS: TestPanic (0.00s)
=== RUN   TestWarnings
    compiler_test.go:43: Recorded Errors=[]yara.CompilerMessage{yara.CompilerMessage{Filename:"", Line:1, Text:"syntax error"}}, Warnings=[]yara.CompilerMessage(nil)
--- PASS: TestWarnings (0.00s)
=== RUN   TestCompilerIncludeCallback
    compiler_test.go:52: Processing include "existing" (from ns="default", file="")
    compiler_test.go:52: Processing include "non-existing" (from ns="default", file="")
    compiler_test.go:73: Compiler returned error on attempt to include non-existing rule: callback failed to provide include resource: non-existing
--- PASS: TestCompilerIncludeCallback (0.00s)
=== RUN   TestIterator
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x0]

runtime stack:
runtime.throw(0x5985c8, 0x2a)
	/usr/lib/go-1.15/src/runtime/panic.go:1116 +0x72
runtime.sigpanic()
	/usr/lib/go-1.15/src/runtime/signal_unix.go:726 +0x4ac

goroutine 11 [syscall]:
runtime.cgocall(0x544e60, 0xc000058dd0, 0x1)
	/usr/lib/go-1.15/src/runtime/cgocall.go:133 +0x5b fp=0xc000058da0 sp=0xc000058d68 pc=0x407ffb
github.com/hillu/go-yara._Cfunc_yr_rules_scan_mem_blocks(0x79c630, 0xc0001003f0, 0x8, 0x5443b0, 0x76b838, 0xc000000000, 0xc000000000)
	_cgo_gotypes.go:1567 +0x4d fp=0xc000058dd0 sp=0xc000058da0 pc=0x5353ad
github.com/hillu/go-yara.(*Rules).ScanMemBlocks.func1(0xc000010098, 0xc0001003f0, 0x0, 0x5c2080, 0xc00000e200, 0x76b838, 0x0, 0x7f5a029ce108)
	/build/golang-github-hillu-go-yara-4.0.5/obj-x86_64-linux-gnu/src/github.com/hillu/go-yara/rules.go:182 +0x145 fp=0xc000058e30 sp=0xc000058dd0 pc=0x540625
github.com/hillu/go-yara.(*Rules).ScanMemBlocks(0xc000010098, 0x5c36c0, 0xc00000e220, 0x0, 0x0, 0x5c2080, 0xc00000e200, 0x0, 0x0)
	/build/golang-github-hillu-go-yara-4.0.5/obj-x86_64-linux-gnu/src/github.com/hillu/go-yara/rules.go:182 +0x285 fp=0xc000058ef0 sp=0xc000058e30 pc=0x53a545
github.com/hillu/go-yara.TestIterator(0xc000130480)
	/build/golang-github-hillu-go-yara-4.0.5/obj-x86_64-linux-gnu/src/github.com/hillu/go-yara/mem_blocks_test.go:54 +0xda fp=0xc000058f80 sp=0xc000058ef0 pc=0x52a4da
testing.tRunner(0xc000130480, 0x59c310)
	/usr/lib/go-1.15/src/testing/testing.go:1123 +0xef fp=0xc000058fd0 sp=0xc000058f80 pc=0x4e206f
runtime.goexit()
	/usr/lib/go-1.15/src/runtime/asm_amd64.s:1374 +0x1 fp=0xc000058fd8 sp=0xc000058fd0 pc=0x471541
created by testing.(*T).Run
	/usr/lib/go-1.15/src/testing/testing.go:1168 +0x2b3

goroutine 1 [chan receive]:
testing.(*T).Run(0xc000130480, 0x58fcf9, 0xc, 0x59c310, 0x489901)
	/usr/lib/go-1.15/src/testing/testing.go:1169 +0x2da
testing.runTests.func1(0xc000001980)
	/usr/lib/go-1.15/src/testing/testing.go:1439 +0x78
testing.tRunner(0xc000001980, 0xc000057cf0)
	/usr/lib/go-1.15/src/testing/testing.go:1123 +0xef
testing.runTests(0xc00000e0a0, 0x685300, 0x27, 0x27, 0xc01331720406f728, 0x8bb31abbc6, 0x69a980, 0xc000057db8)
	/usr/lib/go-1.15/src/testing/testing.go:1437 +0x2fe
testing.(*M).Run(0xc000122000, 0x0)
	/usr/lib/go-1.15/src/testing/testing.go:1345 +0x1eb
github.com/hillu/go-yara.TestMain(0xc000122000)
	/build/golang-github-hillu-go-yara-4.0.5/obj-x86_64-linux-gnu/src/github.com/hillu/go-yara/main_test.go:35 +0x1a5
main.main()
	_testmain.go:125 +0x165
FAIL	github.com/hillu/go-yara	0.024s
FAIL

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (8 by maintainers)

Most upvoted comments

Great catch. Apparently, YARA needs all the function pointers of YR_MEMORY_BLOCK_ITERATOR to be initialized with non-zero pointers (and the structure layout has changed for 4.1.0). The workaround below fixes the issue for me, but I think that this can (and should be) fixed in YARA itself.

--- a/mem_blocks.go
+++ b/mem_blocks.go
@@ -16,6 +16,7 @@ uint8_t* memoryBlockFetchNull(YR_MEMORY_BLOCK*);
 
 YR_MEMORY_BLOCK* memoryBlockIteratorFirst(YR_MEMORY_BLOCK_ITERATOR*);
 YR_MEMORY_BLOCK* memoryBlockIteratorNext(YR_MEMORY_BLOCK_ITERATOR*);
+uint64_t memoryBlockIteratorSize(YR_MEMORY_BLOCK_ITERATOR*);
 */
 import "C"
 import (
@@ -60,9 +61,11 @@ func makeMemoryBlockIteratorContainer(mbi MemoryBlockIterator) (c *memoryBlockIt
 // pool.
 func makeCMemoryBlockIterator(c *memoryBlockIteratorContainer) (cmbi *C.YR_MEMORY_BLOCK_ITERATOR) {
        return &C.YR_MEMORY_BLOCK_ITERATOR{
-               context: callbackData.Put(c),
-               first:   C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorFirst),
-               next:    C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorNext),
+               context:    callbackData.Put(c),
+               first:      C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorFirst),
+               next:       C.YR_MEMORY_BLOCK_ITERATOR_FUNC(C.memoryBlockIteratorNext),
+               file_size:  C.YR_MEMORY_BLOCK_ITERATOR_SIZE_FUNC(C.memoryBlockIteratorSize),
+               last_error: 0,
        }
 }
 
@@ -148,3 +151,8 @@ func memoryBlockIteratorNext(cmbi *C.YR_MEMORY_BLOCK_ITERATOR) *C.YR_MEMORY_BLOC
        c.MemoryBlock = c.MemoryBlockIterator.Next()
        return memoryBlockIteratorCommon(cmbi, c)
 }
+
+//export memoryBlockIteratorSize
+func memoryBlockIteratorSize(cmbi *C.YR_MEMORY_BLOCK_ITERATOR) C.uint64_t {
+       return C.YR_UNDEFINED
+}

I was curious and ran a job on an ARM64 instance (Ubuntu/groovy) and I can reproduce the test failure with v4.0.5. And yes, this is a segmentation fault.

Removing re_lexer.c so that it gets regenerated (needs flex to be installed) made the issue go away.