Skip to content

brk() implementation is racy #10006

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

Closed
juj opened this issue Dec 11, 2019 · 4 comments
Closed

brk() implementation is racy #10006

juj opened this issue Dec 11, 2019 · 4 comments

Comments

@juj
Copy link
Collaborator

juj commented Dec 11, 2019

Emscripten moved to implement brk() in C instead of JS, with implementation

int brk(intptr_t ptr) {
  intptr_t last = (intptr_t)sbrk(0);
  if (sbrk(ptr - last) == (void*)-1) {
    return -1;
  }
  return 0;
}

However the implementation can race in multithreaded setting and produce an incorrect sbrk bump.

Suppose heap size is 2MB, and thread A is calling brk(4MB). last will come out at 2MB, so thread A is about to call sbrk(4MB-2MB) to increase the heap by two megabytes, but let's suppose it pauses there before the call.

Meanwhile, suppose thread B is also calling brk(4MB) to set the heap size to the same size. It computes that it should bump the size by 2MB, so it should also call sbrk(4MB-2MB). Now both thread A and thread B will be calling to bump break limit up by 2 megabytes. They both succeed, and heap will grow from 2MB -> 4MB -> 6MB. But both threads A and B had initially issued a call brk(4MB) to set the heap limit to the same 4MB ceiling!

I am not running into this issue in practice, but just noticed this when glancing over the implemented C code.

@kripken
Copy link
Member

kripken commented Dec 11, 2019

Good point, we made sbrk threadsafe but not brk, it looks like.

Worth fixing, but in most cases brk is not called directly, and both malloc and sbrk are safe, so low-risk. But I opened #10008 to show a clear error in a pthreads build.

kripken added a commit that referenced this issue Dec 12, 2019
#10008)

See #10006 - this will at least get us a clear error from
a user that hits this, until we fix the issue properly.
@Albirair
Copy link

Shouldn't brk now be considered thread-safe considering that it only invokes sbrk which has been made thread-safe since commit d15f2 ? Thus, the only modification needed is removing the #if directive on condition EMSCRIPTEN_PTHREADS .

@kripken
Copy link
Member

kripken commented Apr 20, 2020

@Albirair I think it is still not thread-safe. sbrk itself is, but in brk we call sbrk twice, and there is a possibility for races because of that.

belraquib pushed a commit to belraquib/emscripten that referenced this issue Dec 23, 2020
emscripten-core#10008)

See emscripten-core#10006 - this will at least get us a clear error from
a user that hits this, until we fix the issue properly.
@stale
Copy link

stale bot commented Jun 3, 2021

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.

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

No branches or pull requests

3 participants