Skip to content

Remove GLV unlocking at all functions which process data modifiable in a second thread#723

Open
larskanis wants to merge 1 commit into
masterfrom
DFVULN-801-2
Open

Remove GLV unlocking at all functions which process data modifiable in a second thread#723
larskanis wants to merge 1 commit into
masterfrom
DFVULN-801-2

Conversation

@larskanis
Copy link
Copy Markdown
Collaborator

@larskanis larskanis commented Jun 7, 2026

This removes possible VM crashs when data to be sent is modified/cleared in a second thread.
It works by keeping the GVL lock for libpq functions that don't immediately process all the data and don't make a copy of it.
These are the PQsend*, PQexec* and some related functions.

Since pg-1.3 all the blocking functions or states are avoided by using the non-blocking API of libpq.
Therefore holding the GVL somewhat longer shouldn't matter that much.

Having some libpq function with and without unlocked GVL, results in rb_thread_call_with_gvl() sometimes needed and sometimes not to process callbacks.
Therefore ruby_thread_has_gvl_p() is used to check if it's needed on ruby<4.0.
In ruby-4.0+ rb_thread_call_with_gvl() doesn't care about whether GVL is already locked or not, so that it can be called in both cases.

Fixes #721

@larskanis larskanis changed the title Dfvuln 801 2 Remove GLV unlocking at all functions which process data modifiable in a second thread Jun 8, 2026
@larskanis larskanis force-pushed the DFVULN-801-2 branch 6 times, most recently from 2facd7a to b9a2e30 Compare June 8, 2026 08:31
…n a second thread

This removes possible VM crashs when data to be sent is modified/cleared in a second thread.
It works by keeping the GVL lock for libpq functions that don't immediately process all the data and don't make a copy of it.
These are the `PQsend*`, `PQexec*` and some related functions.

Since pg-1.3 all the blocking functions or states are avoided by using the non-blocking API of libpq.
Therefore holding the GVL somewhat longer shouldn't matter that much.

Having some libpq function with and without unlocked GVL, results in `rb_thread_call_with_gvl()` sometimes needed and sometimes not to process callbacks.
Therefore `ruby_thread_has_gvl_p()` is used to check if it's needed on ruby<4.0.
In ruby-4.0+ `rb_thread_call_with_gvl()` doesn't care about whether GVL is already locked or not, so that it can be called in both cases.

Fixes #721
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

Successfully merging this pull request may close these issues.

DFVULN-801: Query Parameter Lifetime Bug Causes Heap Use-After-Free

1 participant