gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source.
https://gno.land/
Other
882 stars 364 forks source link

Usage of `unsafe` #802

Open schollz opened 1 year ago

schollz commented 1 year ago

I've started porting some needed Go code (math.Sin, math.Cos) to Gno and I'm noticing that I'm running into small roadblocks with packages that use unsafe. Is unsafe out of scope for Gno? It is okay if so, it seems like this is not imported anywhere in .gno files... I'm curious the reason (for determinism? preventing memory access?) The removal of unsafe does seem to throw wrenches in simple things, like an implementation of math.Sin, where the stdlib implementation uses it to retrieve IEEE 754 binaries of floats. I'm sure I can workaround them for my purposes, I was just wondering about the context.

schollz commented 1 year ago

I'm still interested in the discussion around unsafe exclusion - but for my particular case I found "safe" implementations further back in the Go history (pre Go1 !) for Sine/Cosine: https://github.com/gnolang/gno/pull/805 so that's not a problem.

thehowl commented 1 year ago

I've not personally had any discussion re: unsafe, but to me there's strong reasons to not include it as it would be hard to have unsafe on Gno without amplifying the risk of allowing RCEs or other exploits. "What" unsafe should do is also up for the debate I would say (it can't be just the same as go's unsafe, as that would allow the program in the gnovm to access and modify data of gno.land or in general users of the vm), so it would probably need to operate on a virtual memory, but even then with virtual memory I can very easily see this having problems (ie. accessing memory that a program should not be allowed to access, such as another package's unexported variable).

For the specific case of float64 bits, I think it makes sense to implement these four as native functions in the math package. For most things, I don't necessarily see the point in adding unsafe - even for a reflect package, I would advise adding it as mostly-native code instead of having a gno package play with memory.

schollz commented 1 year ago

A minimal attack surface is definitely ideal. Honestly I did not realize how much unsafe is being used in Go. I think my current thought is that it would be easier to fork Go code if Gno has an unsafe implementation. As you mention, I think it makes sense to implement functions as native Gno code when possible but the tradeoff will likely be increased development time.