Skip to content

Fix SSH2 resource ownership and stream error handling#103

Open
binaryfire wants to merge 1 commit into
php:masterfrom
binaryfire:fix/ssh2-resource-stream-lifecycle
Open

Fix SSH2 resource ownership and stream error handling#103
binaryfire wants to merge 1 commit into
php:masterfrom
binaryfire:fix/ssh2-resource-stream-lifecycle

Conversation

@binaryfire

Copy link
Copy Markdown

Summary

This fixes one connected set of SSH2 resource-ownership and stream-contract bugs:

  • child channels, listeners, public-key handles, and SFTP handles no longer call libssh2 after their parent session has closed
  • direct URL-wrapper sessions are registered before authentication and released on every success or failure path
  • temporary SFTP resources used by stat, unlink, rename, mkdir, and rmdir are released after each operation
  • ssh2_poll() rejects channels and listeners whose parent session is closed
  • nonblocking EAGAIN is reported as zero-byte backpressure on modern PHP
  • other channel and SFTP failures remain errors instead of being changed into EOF
  • accepted forward channels initialize their timeout state
  • the fetched-stream allocation rollback decrements the shared count rather than the pointer

These changes belong together because they share one ownership graph. Landing only part of it can leave streams that retain resources but still dereference released native state, or fix successful wrapper ownership while leaving failure paths and one-shot operations unbalanced.

No public API changes are required. Explicitly closing a session now makes its remaining child resources fail safely while their PHP-side cleanup still completes.

Testing

Added PHPT coverage for:

  • direct-wrapper success and authentication-failure cleanup
  • one-shot SFTP reference release
  • channel, listener, poll, public SFTP, file-stream, and directory-stream behavior after disconnect
  • nonblocking channel backpressure, channel errors, and clean EOF
  • SFTP errors versus clean file and directory completion

The extension builds cleanly against PHP 8.4 and libssh2 1.11. The complete suite was also run against a local OpenSSH fixture; its remaining failures match an unchanged master build and come from existing fixture assumptions.

Guard every native channel, listener, public-key, and SFTP child operation with the owning session lifetime. Keep cleanup on the Zend side balanced after explicit disconnects, and prevent polling or stream operations from dereferencing released libssh2 state.

Make direct wrapper connection and authentication ownership transactional, release temporary SFTP resources after one-shot operations, and correct the fetched-stream refcount rollback.

Preserve channel and SFTP errors as errors, reserve EOF for clean zero-byte completion, normalize EAGAIN as nonblocking backpressure, and initialize accepted-channel timeout state. Add focused PHPT coverage for ownership, descriptor release, parent loss, polling, backpressure, errors, and clean completion.
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