-
Notifications
You must be signed in to change notification settings - Fork 1.2k
otherlibs/systhreads/st_stubs.c: Avoid free of uninitialized pointer #13401
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are not supposed to call caml_c_thread_unregister on the main thread. Nevertheless it's good to initialise the signal_stack field.
|
This also looks fine to me. Thanks! The PR as-is targets I think that this would deserve a Changes entry as it fixes a user-facing issue, and to credit your external contribution. |
|
Hang on, I'll try to retarget it ... |
|
Please add a Changes entry but
while it is good to initialize memory, is it technically a bug to free a block whose memory was (partly) left uninitialized? |
My understanding is that the bug reported is not that we free a If I read the code correctly, the code will still fail now that |
This is correct, you call free on an uninitialized pointer (when glibc tunables are used to pollute uninitialized memory). From the stack trace notice the pointer is Note
Will modify in a moment. |
Calling caml_c_thread_unregister() will (amongst many other things) free the caml_thread_t signal_stack entry of the current thread. The OCaml runtime initializes the main thread using special code in caml_thread_domain_initialize_hook, but this leaves the signal_stack entry uninitialized. If you use glibc tunables to enable malloc checking, and especially use the malloc.perturb feature[1], then uninitialized areas of memory are filled with a repeating pattern. This causes the process to crash if you free an uninitialized pointer. Thus any program which calls caml_c_thread_unregister on the main thread, and is using glibc malloc checking, will crash. Fix this by initializing the signal_stack to NULL (since free(NULL) is permitted and does nothing). This was found when debugging a problem in the nbdkit OCaml plugin[2]. [1] https://www.gnu.org/software/libc/manual/html_node/Memory-Allocation-Tunables.html [2] https://discuss.ocaml.org/t/free-uninitalized-data-when-calling-caml-c-thread-unregister-on-the-main-thread/15198 Fixes: ocaml#13400 Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
My impression is that the code of |
The plan to fix this in nbdkit is to not call
Shouldn't |
This does not sound like a user-facing issue in this sense either; per the documentation |
|
Anyway, I think the current change is good -- even if indeed the users should maybe rethink their implementation. (I see that over at #13400 @gadmm has provided useful feedback on how to write the code differently. If you do happen to come up with additions to the current API to improve @rwmjones' use-case, I would be happy to consider implementing them or reviewing their implementation. For now it look like a purely user-side solution could be reasonable, so maybe there is no need.) |
otherlibs/systhreads/st_stubs.c: Avoid free of uninitialized pointer (cherry picked from commit 760ae23)
Thanks: Guillaume Munch-Maccagnoni and Gabriel Scherer Link: ocaml/ocaml#13400 Link: ocaml/ocaml#13401
Calling caml_c_thread_unregister() will (amongst many other things) free the caml_thread_t signal_stack entry of the current thread. The OCaml runtime initializes the main thread using special code in caml_thread_domain_initialize_hook, but this leaves the signal_stack entry uninitialized.
If you use glibc tunables to enable malloc checking, and especially use the malloc.perturb feature[1], then uninitialized areas of memory are filled with a repeating pattern. This causes the process to crash if you free an uninitialized pointer.
Thus any program which calls caml_c_thread_unregister on the main thread, and is using glibc malloc checking, will crash.
Fix this by initializing the signal_stack to NULL (since free(NULL) is permitted and does nothing).
This was found when debugging a problem in the nbdkit OCaml plugin[2].
[1] https://www.gnu.org/software/libc/manual/html_node/Memory-Allocation-Tunables.html
[2] https://discuss.ocaml.org/t/free-uninitalized-data-when-calling-caml-c-thread-unregister-on-the-main-thread/15198
Fixes: #13400