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

Enable reentrant execution #8

Merged
merged 20 commits into from
Oct 6, 2024
Merged

Enable reentrant execution #8

merged 20 commits into from
Oct 6, 2024

Conversation

logmanoriginal
Copy link
Owner

No description provided.

Callers are currently responsible to ensure that handles are accessed
sequentially. Otherwise, the behavior is undefined.

libssh2_init() is not reentrant because the function is not thread-
safe according to the libssh2 documentation. Note that this also
applies to libssh2_session_init*(), which calls libssh2_init()
internally as convenience function. Though, this is not an issue
in lvssh2 because libssh2_session_init*() does not work unless
libssh2_init() has been called (library path must be initialized).

There are no automated tests to validate correct behavior because it
is almost impossible to validate correct behavior of parallel threads
as race-conditions are non-deterministic. The best we can do is add
locks to prevent users from accidentally corrupting memory by calling
multiple functions on a single object but this is not the scope of
this commit.
This adds a semaphore to the session handle to prevent callers from
executing multiple functions on one session in parallel, which
could result in corrupted memory and undefined behaviour.

The semaphore is session-specific to allow multiple sessions to be
used at once. It is currently not shared with channels related to a
session.
The SFTP subsystem uses the semaphore of the session it was created
from. This is necessary because the SFTP subsystem utilizes the TCP
connection of the corresponding session.

Note that this affects both the SFTP and SFTP Handle.
This adds a semaphore to the channel handle to prevent concurrent
access to the channel. Since channels in libssh2 utilize the TCP
connection of the session it was created from, the semaphore used
for the channel is shared from the session. This ensures that all
functions utilizing the session do not conflict with another.
When releasing resources, the session handle must be locked to prevent
concurrent access. Otherwise, memory corruption might occur.
This adds a unique semaphore to the host key database to lock access
for concurrent operations. The semaphore is not shared with the
session handle because, once created, the session object is not
used anymore (only needed for the initial creation of the handle).
This ensures that host key data is not changed while writing data
to the database.
This adds a semaphore to agent functions. The agent shares the
semaphore with the session because, for remote agents, the TCP
connection of the session is used.

Identities also share the semaphore of the agent to prevent writing
into memory that is used by other functions.
@logmanoriginal logmanoriginal marked this pull request as ready for review October 6, 2024 14:37
@logmanoriginal logmanoriginal merged commit 9221503 into main Oct 6, 2024
1 check passed
@logmanoriginal logmanoriginal deleted the reentrancy branch October 6, 2024 14:37
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.

1 participant