Skip to content

Commit

Permalink
handle allocations for problematic structs to avoid sharing pointers-…
Browse files Browse the repository at this point in the history
…to-pointers with C (from Go) (#82)

* alternative verify post

* manually allocate proxy object to prevent sharing Go heap with C

* Revert "alternative verify post"

This reverts commit 841ff78.

* manually allocate proxy object to prevent sharing Go heap with C

* pass flattened messages to fil_hash_verify to prevent pointer-to-pointer issues with CGO

* rename symbols within custom allocate methods

* run go test with cgocheck=2

* delete temporary branches from circleci config
  • Loading branch information
laser authored May 5, 2020
1 parent a0014b1 commit 0c54e22
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 108 deletions.
5 changes: 2 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ workflows:
branches:
only:
- master
- feat/lint-during-build
- build_darwin_cgo_bindings
- publish_darwin_staticlib:
filters:
Expand Down Expand Up @@ -320,13 +319,13 @@ commands:
no_output_timeout: 60m
- run:
name: Test project
command: RUST_LOG=info go test -p 1 -timeout 60m
command: GODEBUG=cgocheck=2 RUST_LOG=info go test -p 1 -timeout 60m
no_output_timeout: 60m
compile_tests:
steps:
- run:
name: Build project and tests, but don't actually run the tests (used to verify that build/link works with Darwin)
command: RUST_LOG=info go test -run=^$
command: GODEBUG=cgocheck=2 RUST_LOG=info go test -run=^$
restore_parameter_cache:
steps:
- restore_cache:
Expand Down
10 changes: 5 additions & 5 deletions bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ func Verify(signature *Signature, digests []Digest, publicKeys []PublicKey) bool

// HashVerify verifies that a signature is the aggregated signature of hashed messages.
func HashVerify(signature *Signature, messages []Message, publicKeys []PublicKey) bool {
messagesPtrs := make([]string, len(messages))
var flattenedMessages string
messagesSizes := make([]uint, len(messages))
for idx, msg := range messages {
messagesPtrs[idx] = string(msg)
messagesSizes[idx] = uint(len(msg))
for idx := range messages {
flattenedMessages = flattenedMessages + string(messages[idx])
messagesSizes[idx] = uint(len(messages[idx]))
}

flattenedPublicKeys := make([]byte, PublicKeyBytes*len(publicKeys))
for idx, publicKey := range publicKeys {
copy(flattenedPublicKeys[(PublicKeyBytes*idx):(PublicKeyBytes*(1+idx))], publicKey[:])
}

isValid := generated.FilHashVerify(string(signature[:]), messagesPtrs, messagesSizes, uint(len(messages)), string(flattenedPublicKeys), uint(len(flattenedPublicKeys)))
isValid := generated.FilHashVerify(string(signature[:]), flattenedMessages, uint(len(flattenedMessages)), messagesSizes, uint(len(messagesSizes)), string(flattenedPublicKeys), uint(len(flattenedPublicKeys)))

return isValid > 0
}
Expand Down
48 changes: 0 additions & 48 deletions generated/cgo_helpers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions generated/customallocs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package generated

/*
#cgo LDFLAGS: -L${SRCDIR}/.. -lfilcrypto
#cgo pkg-config: ${SRCDIR}/../filcrypto.pc
#include "../filcrypto.h"
#include <stdlib.h>
#include "cgo_helpers.h"
*/
import "C"
import (
"unsafe"
)

// AllocateProxy allocates a FilPrivateReplicaInfo proxy object in the C heap,
// returning a function which, when called, frees the allocated memory. This
// method exists because the default c-for-go allocation strategy allocates a
// C struct with a field whose values is a pointer into the Go heap, which is
// not permitted by the most strict CGO check (cgocheck=2).
func (x *FilPrivateReplicaInfo) AllocateProxy() func() {
mem := allocFilPrivateReplicaInfoMemory(1)
proxy := (*C.fil_PrivateReplicaInfo)(mem)
proxy.cache_dir_path = C.CString(x.CacheDirPath)
proxy.comm_r = *(*[32]C.uint8_t)(unsafe.Pointer(&x.CommR))
proxy.registered_proof = (C.fil_RegisteredPoStProof)(x.RegisteredProof)
proxy.replica_path = C.CString(x.ReplicaPath)
proxy.sector_id = (C.uint64_t)(x.SectorId)

x.ref81a31e9b = proxy

return func() {
C.free(unsafe.Pointer(proxy.cache_dir_path))
C.free(unsafe.Pointer(proxy.replica_path))
C.free(unsafe.Pointer(proxy))
}
}

// AllocateProxy allocates a FilPoStProof proxy object in the C heap,
// returning a function which, when called, frees the allocated memory.
func (x *FilPoStProof) AllocateProxy() func() {
mem := allocFilPoStProofMemory(1)
proxy := (*C.fil_PoStProof)(mem)

proxy.registered_proof = (C.fil_RegisteredPoStProof)(x.RegisteredProof)
proxy.proof_len = (C.size_t)(x.ProofLen)
proxy.proof_ptr = (*C.uchar)(unsafe.Pointer(C.CString(x.ProofPtr)))

x.ref3451bfa = proxy

return func() {
C.free(unsafe.Pointer(proxy.proof_ptr))
C.free(unsafe.Pointer(proxy))
}
}
55 changes: 29 additions & 26 deletions generated/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0c54e22

Please sign in to comment.