nimcrypto icon indicating copy to clipboard operation
nimcrypto copied to clipboard

sysrand leaks threadvar variables

Open n5m opened this issue 3 years ago • 1 comments

Calling sysrand.randomBytes causes Valgrind to mark memory as "possibly lost."

Example

# proof.nim
import nimcrypto/sysrand

var x: int
discard randomBytes(addr(x), sizeof(x))

Compile

$ nim c --gc:arc -d:useMalloc proof.nim 
Hint: used config file '/home/user/nim/config/nim.cfg' [Conf]
Hint: used config file '/home/user/nim/config/config.nims' [Conf]
....................
Hint:  [Link]
Hint: 41955 lines; 0.729s; 49.098MiB peakmem; Debug build; proj: /home/user/nimcrypto/proof.nim; out: /home/user/nimcrypto/proof [SuccessX]

Run

$ valgrind --error-exitcode=1 --leak-check=yes ./proof
[[Elided output]]
==989== LEAK SUMMARY:
==989==    definitely lost: 0 bytes in 0 blocks
==989==    indirectly lost: 0 bytes in 0 blocks
==989==      possibly lost: 24 bytes in 1 blocks
==989==    still reachable: 0 bytes in 0 blocks
==989==         suppressed: 0 bytes in 0 blocks
==989== 
==989== For counts of detected and suppressed errors, rerun with: -v
==989== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

This "leak" happens because the global RNG is marked as {.threadvar.}: https://github.com/cheatfate/nimcrypto/blob/a065c1741836462762d18d2fced1fedd46095b02/nimcrypto/sysrand.nim#L110

but this seems like marking the variable as {.threadvar.} is avoidable entirely. After examining the way gSystemRng is initialized (when being compiled on Linux), https://github.com/cheatfate/nimcrypto/blob/a065c1741836462762d18d2fced1fedd46095b02/nimcrypto/sysrand.nim#L112-L127 it seems that we could have

 var gSystemRng: SystemRng = newSystemRNG() ## System thread global RNG 

which does not have {.threadvar.}. Are there any issues I am overlooking with this approach?

I agree that this isn't a genuine leak since it is a global variable and the memory always still has a reference, but having Valgrind not complain would be a nice feature to have.

n5m avatar Nov 01 '20 00:11 n5m

At this point, since Nimcrypto requires Nim 1.6 regardless, and https://nim-lang.org/docs/sysrand.html is available (different implementation, same name, same concept/intention) in the Nim standard library, is that an appropriate replacement for Nimcrypto's own sysrand?

tersec avatar Feb 29 '24 23:02 tersec