Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible with hashbrown 0.11 #326

Open
xu-cheng opened this issue Mar 17, 2021 · 2 comments
Open

Incompatible with hashbrown 0.11 #326

xu-cheng opened this issue Mar 17, 2021 · 2 comments

Comments

@xu-cheng
Copy link
Contributor

xu-cheng commented Mar 17, 2021

I write enclave code strictly in no_std and use hashbrown as one of the transitive dependencies. However, it fails to compile after upgrading hashbrown to 0.11. It fails at linker step with the following messages:

/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::error::os_err':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/error.rs:96: undefined reference to `__xpg_strerror_r'
/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::util_libc::open_readonly':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/util_libc.rs:110: undefined reference to `open64'
/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::use_file::getrandom_inner::{{closure}}':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/use_file.rs:36: undefined reference to `read'
/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::use_file::wait_until_rng_ready':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/use_file.rs:104: undefined reference to `poll'
/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::use_file::wait_until_rng_ready::{{closure}}':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/use_file.rs:99: undefined reference to `close'
/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::use_file::Mutex::lock':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/use_file.rs:124: undefined reference to `pthread_mutex_lock'
/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::use_file::Mutex::unlock':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/use_file.rs:128: undefined reference to `pthread_mutex_unlock'
/usr/local/bin/ld: target/debug/libenclave.a(getrandom-1afbd7620d110fa6.getrandom.3csxlzm7-cgu.0.rcgu.o): in function `getrandom::imp::getrandom':
/home/USER/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/linux_android.rs:45: undefined reference to `syscall'
collect2: error: ld returned 1 exit status

The pitfall comes from that hashbrown 0.11 depends on getrandom 0.2. And getrandom despite being a no_std library will always use Linux syscall if the target triple is *-linux-*. See its document for more detail.

Ultimately, I think this just shows a fundamental issue that we tell rust to build enclave code in x86_64-unknown-linux-gnu target when in reality we are actually using something like x86_64-unknown-none-sgx. As such, getrandom got the wrong impression that we are on Linux and it is safe to use Linux syscall.

Of course, we can fork and patch getrandom. But IMHO, patching crates for sgx are red herring in terms of maintenance, stability, or even security (as bug fixes in upstream may not be applied in time). Not mentioning it splits the eco systems. I also believe it is infeasible to patch every crates whenever we encounter similar issues. So my question is whether there is a better systematic approach to address the underlying issue.

Thanks.

@dingelish
Copy link
Contributor

dingelish commented Mar 17, 2021

Hi @xu-cheng , thanks for your report.

I totally agree on every word you mentioned above.

maintain a bunch of forked crates can help us with (1) stability and (2) compatibility and (3) features, and something suffers a lot (1) freshness, (2) security. but overall I slightly tend to maintain an isolated ecosystem. and in production, i believe most products vendor their dependencies and then maintain their vendored sources.

on the getrandom issue, i'd say the only doable way is to maintain a fork of getrandom. as you already know, quality of random number is critical to Intel SGX enclaves, while it may not mean much to many of other platforms. getrandom lays on the bottom of the entire crate dependency graph and i'd strongly recommend user to maintain their own fork.

and i believe hashbrown is a very very special case: std has a built-in hashbrown (v0.9.0 as of today). and one principle you may know is "we should not have 2 different versions of the same library in the same dependency tree". so I'd say if you need hashbrown, first try if you can use the libstd's built-in one.

@xu-cheng
Copy link
Contributor Author

and i believe hashbrown is a very very special case: std has a built-in hashbrown (v0.9.0 as of today)

FYI, hashbrown is commonly used as drop-in for essentially alloc::collections::hash_map in no_std crates. This use case will likely exist until std hashmap is moved to alloc in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants