php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73438 Calling new ssh_disconnect() function results in segfault
Submitted: 2016-11-01 21:16 UTC Modified: 2021-02-09 17:10 UTC
Votes:13
Avg. Score:3.8 ± 1.5
Reproduced:12 of 12 (100.0%)
Same Version:4 (33.3%)
Same OS:2 (16.7%)
From: ben at indietorrent dot org Assigned: cmb (profile)
Status: Duplicate Package: ssh2 (PECL)
PHP Version: 7.0.12 OS: Ubuntu 16.04
Private report: No CVE-ID: None
 [2016-11-01 21:16 UTC] ben at indietorrent dot org
Description:
------------
Summary

Prior to PHP 7 (ssh2 version 0.13), disconnections were performed implicitly by calling unset() on the associated resource. And while it was nice to see an explicit ssh2_disconnect() method added in PHP 7 (ssh2 version 1.0), calling it seems to result in a segfault.

Note: Passing a disconnect callback function to ssh2_connect() seems still to be supported, but this approach results in a segfault, too.

This crashing makes it impossible to terminate SSH connections gracefully. As such, when ssh2_connect() is wrapped in any sort of loop, every connection persists on the remote server until the PHP script has finished executing completely. This can exhaust resources on the remote server very quickly and result in a DoS scenario, in effect.



PHP Version

$ php -v
PHP 7.0.12-1+deb.sury.org~xenial+1 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.12-1+deb.sury.org~xenial+1, Copyright (c) 1999-2016, by Zend Technologies



PECL ssh2 Version

$ pecl info ssh2
About pecl.php.net/ssh2-1.0
===========================
Release Type          PECL-style PHP extension (source code)
Name                  ssh2
Channel               pecl.php.net
Summary               Bindings for the libssh2 library
Description           Provides bindings to the functions of libssh2
                      which implements the SSH2 protocol.
                       libssh2 is available from http://libssh2.org/

                       ssh2 1.0 and above is PHP 7 only. To install a
                      version that is PHP 5 compatible you can run
                      'pecl install ssh2-0.13'

                       Note that reaching version 1.0 does NOT
                      indicate we've reached a stable release.
Maintainers           Casper Langemeijer <langemeijer@php.net> (lead)
                      Pierre Joye <pierre@php.net> (lead)
                      Mike Sullivan <mikesul@php.net> (lead, inactive)
                      Sara Golemon <pollita@php.net> (lead, inactive)
Release Date          2016-06-12 15:05:45
Release Version       1.0 (alpha)
API Version           1.0 (beta)
License               PHP License (http://www.php.net/license)
Release Notes         - Release for PHP 7 (Sean DuBois)
                      - Made win32 builds depend on zlib and openssl
                      extensions (Credomane Evonguard)
                      - Add blocking call to php_ssh2_direct_tcpip
                      (Credomane Evonguard)
                      - Added explicit ssh2_disconnect function
                      (Credomane Evonguard)
                      - Fixed bug #72150 - Fixing segfault when
                      passing env variables (Krakjoe)
Required Dependencies PHP version 7.0.0-8.0.0
                      PEAR installer version 1.4.0 or newer
package.xml version   2.0
Last Modified         2016-07-16 18:57
Previous Installed    - None -
Version



Installed modules:

$ php -m
[PHP Modules]
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gettext
hash
iconv
imagick
imap
intl
json
libxml
mbstring
mcrypt
memcache
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
pspell
readline
recode
Reflection
session
shmop
SimpleXML
soap
sockets
SPL
sqlite3
ssh2
standard
sysvmsg
sysvsem
sysvshm
tidy
tokenizer
wddx
xml
xmlreader
xmlrpc
xmlwriter
xsl
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache



php.ini Changes

[None]

Test script:
---------------
https://gist.github.com/cbj4074/7b8b3509150d35a786a51dce395bf9c6

This example uses public-key authentication to connect to the remote server. I don't know whether or not the segfault occurs in the same way when using password authentication.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-11-07 21:44 UTC] ben at indietorrent dot org
I found a few minutes in which to reproduce the issue with the most basic example possible, and PHP still segfaults:


<?php

$ssh = ssh2_connect('localhost', 22, array('hostkey'=>'ssh-rsa,ssh-dss'));

// The segfault happens with both password and public-key authentication.

#ssh2_auth_pubkey_file($ssh, 'root', '/root/.ssh/php-ssh2-test.pub', '/root/.ssh/php-ssh2-test');

ssh2_auth_password($ssh, 'root', 'password');

$sftp = ssh2_sftp($ssh);

ssh2_disconnect($ssh);

exit;



P.S. The ssh_disconnect() function isn't documented in the PHP manual. I do realize that ssh2-1.0 is still considered to be non-stable, but given that ssh-0.13 isn't API-compatible with PHP 5, it seems prudent to add it to the manual and note its requirement to be PECL ssh2 >= 1.0.
 [2016-11-14 06:02 UTC] krakjoe@php.net
-Assigned To: +Assigned To: seander
 [2016-11-14 06:02 UTC] krakjoe@php.net
Assigning this to Sean, much work was started in ssh2 and it does not look finished.
 [2017-10-24 06:07 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: seander +Assigned To:
 [2019-06-02 09:46 UTC] shariefjamiel at gmail dot com
I get this problem too, just trying the examples on the page. The segmentation fault happens when closing the connection.
 [2020-07-21 16:27 UTC] jordanhomsher at gmail dot com
This snippet:
<?php
...
$sftp = ssh2_sftp($sshConn);
ssh2_disconnect($sshConn);
echo 'ssh2 disconnected'.PHP_EOL;
die;
?>

Prints:
ssh2 disconnected
Segmentation fault
---------

This seems to suggest that the segfault likely is not happening within the ssh2_disconnect function but rather stems from the fact that an SSH2 SFTP resource has persisted longer than the SSH connection it was initialized with.

To test this: call unset($sftp); before calling ssh2_disconnect($sshConn);. This has avoided the segmentation fault in my tests.

The issue could be handled more gracefully, however, there is at least a viable workaround in the meantime.

OS: Debian 10
PHP: 7.3.19
Method: CLI
 [2021-02-09 17:10 UTC] cmb@php.net
-Status: Open +Status: Duplicate -Assigned To: +Assigned To: cmb
 [2021-02-09 17:10 UTC] cmb@php.net
Closing as duplicate of bug #79631.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 17:01:32 2024 UTC