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

Deadlock in when poll is hooked by coroutine lib #355

Closed
asurdo opened this issue Apr 4, 2023 · 4 comments
Closed

Deadlock in when poll is hooked by coroutine lib #355

asurdo opened this issue Apr 4, 2023 · 4 comments

Comments

@asurdo
Copy link

asurdo commented Apr 4, 2023

I meet a deadlock case when using 'getrandom_inner' in libco environment, and libco will hook poll.

co1 and co2 are two coroutine, and this happen at the first call of getrandom_inner: co1 poll and switch to co2, co2 deadlock when call mutex.lock

@newpavlov
Copy link
Member

newpavlov commented Apr 4, 2023

Do you mean that libco modifies polling of /dev/random to a yielding operation? If so, I would say it's a clear misuse of getrandom (and, arguably, of Rust code in general). You mix asynchronous operation with synchronous locking primitive. Both must be either synchronous, or asynchronous, not mixed.

You could "fix" it by using a patched version of getrandom tailored for libco environment, but it's likely you will encounter a heap of similar issues in other Rust crates.

@asurdo
Copy link
Author

asurdo commented Apr 6, 2023

Yes, the yield in libco's poll is what I mean.

But getrandom is a very general function and will be called in any situation, which means this function should be extremely safe, and the behavior need be predictable. So there should be a not infinity timeout and make a fast fail with a assert.

In another case, if /dev/random is not readable, dose the poll wait forever?

@newpavlov
Copy link
Member

newpavlov commented Apr 6, 2023

But getrandom is a very general function and will be called in any situation

Not in situations where you break fundamental assumptions used in Rust. We can not be and will not be responsible for situations where you intercept syscalls, fundamentally change their behavior, and change threading model under our foot. At the very least you (read, libco) should also intercept the futex syscall, which is used by Rust's std for implementing Mutex and other synchronization primitives on Linux.

if /dev/random is not readable, dose the poll wait forever?

Yes, it's possible in low-entropy scenarios (e.g. on virtual machines early in the boot process). Security is one of the highest priorities for us. But we may introduce an option for explicitly opting-in into less blocking, but potentially less secure version of getrandom. But note that your deadlock is unlikely to be caused by this.

@asurdo
Copy link
Author

asurdo commented Apr 7, 2023

Ok, I understand that it's actually the limitations of libco, but I was truly confused when it happened in such a general function.

@asurdo asurdo closed this as completed Apr 7, 2023
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