Skip to content

Race condition on synchronous call paths when timeout occurs and late remote response arrives #1519

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
procode-rd opened this issue Oct 18, 2024 · 1 comment · Fixed by #1531

Comments

@procode-rd
Copy link

Hi,

I've tried quickly to create pull request with proposed fix but it seems this is not such easy as it could be :)
Nevertheless, on all paths with synchronous calls in SftpSession class callbacks does not check if "timeout path" has processed in other thread and already closed wait handle through using.dispose. This leads later to receive exception with this stack (as example for initial place calling from "Exists"):

   System.ObjectDisposedException: Safe handle has been closed.
Object name: 'SafeHandle'.
   at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
   at Interop.Kernel32.SetEvent(SafeWaitHandle handle)
   at System.Threading.EventWaitHandle.Set()
   at Renci.SshNet.Sftp.SftpSession.<>c__DisplayClass60_0.<RequestRealPath>b__0(SftpNameResponse response)
   at Renci.SshNet.Sftp.SftpSession.HandleResponse(SftpResponse response)
   at Renci.SshNet.Sftp.SftpSession.TryLoadSftpMessage(Byte[] packetData, Int32 offset, Int32 count)
--- End of stack trace from previous location ---
   at Renci.SshNet.Sftp.SftpSession.RequestRealPath(String path, Boolean nullOnError)
   at Renci.SshNet.Sftp.SftpSession.GetCanonicalPath(String path)
   at Renci.SshNet.SftpClient.Exists(String path)

When calling thread will finish with timeout (finally disposing wait handle) and response will arrive at that point, im my opinion processing of it does not make sense as library already started or is going through timeout/error path.
Hence, in each place I would suggest checking this and not processing "late response" coming in. Such as:
image

I did not analyse TPL path (async), so that might be something to be done.

Thanks!

@Rob-Hague
Copy link
Collaborator

I suppose the simple way would be to catch and ignore ObjectDisposedException when calling Set. The async path uses TaskCompletionSource and would not suffer the same problem

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 a pull request may close this issue.

2 participants