This package passes uintptr to C functions, which is not safe. It can cause memory corruption in rare cases. I did not try to reproduce this bug with this package, because it is subtle. However, we have a package with similar code, and we ended up with a memory corruption bug: DataDog/zstd#90 . I'm filing this issue because I noticed this package uses the same pattern, so it probably has the same problem.
The unlucky sequence is:
- Code evaluates the uintptr from a Go pointer to a variable on the stack.
- Code calls the Cgo wrapper.
- The Go runtime decides this goroutine needs a larger stack, and copies it somewhere else. It fixes the pointers to variables on the stack. It cannot fix the uintptr variable, since it does not think it is a pointer.
- Another thread uses the previous stack and changes the contents.
- The C code casts the uintptr to a pointer, then reads from the wrong memory.
One example piece of code that does this is: https://github.com/valyala/gozstd/blob/master/gozstd.go#L17 , however there are many others. In many cases, I think using unsafe.Pointer instead will not impact the performance of gozstd. For example, the Writer API already copies data into its own heap-allocated buffer, before calling Cgo.
For details, see my reproduction of this problem: https://github.com/evanj/cgouintptrbug
This package passes uintptr to C functions, which is not safe. It can cause memory corruption in rare cases. I did not try to reproduce this bug with this package, because it is subtle. However, we have a package with similar code, and we ended up with a memory corruption bug: DataDog/zstd#90 . I'm filing this issue because I noticed this package uses the same pattern, so it probably has the same problem.
The unlucky sequence is:
One example piece of code that does this is: https://github.com/valyala/gozstd/blob/master/gozstd.go#L17 , however there are many others. In many cases, I think using
unsafe.Pointerinstead will not impact the performance of gozstd. For example, the Writer API already copies data into its own heap-allocated buffer, before calling Cgo.For details, see my reproduction of this problem: https://github.com/evanj/cgouintptrbug