php / pecl-networking-ssh2

Bindings for the libssh2 library
http://pecl.php.net/package/ssh2
Other
51 stars 58 forks source link

Bug #79757 segfaults #43

Closed qjavax closed 3 years ago

qjavax commented 4 years ago

fixed segfaults connecting to not existing host or trying to acess file with file_get_contents() As mentioned here not sending unitialized variable to zend_list_delete

remicollet commented 3 years ago

Still have a build warning

/work/GIT/pecl-and-ext/ssh2/ssh2_fopen_wrappers.c:473:5: warning: 'zsession.value.res' may be used uninitialized in this function [-Wmaybe-uninitialized]
  473 |  if (Z_RES(zsession)) {
      |     ^
In file included from /opt/remi/php80/root/usr/include/php/Zend/zend.h:27,
                 from /opt/remi/php80/root/usr/include/php/main/php.h:31,
                 from /work/GIT/pecl-and-ext/ssh2/ssh2_fopen_wrappers.c:23:
/opt/remi/php80/root/usr/include/php/Zend/zend_types.h:836:37: warning: 'zsftp.value.res' may be used uninitialized in this function [-Wmaybe-uninitialized]
  836 | #define Z_RES(zval)     (zval).value.res
      |                                     ^
qjavax commented 3 years ago

actually the zsession is not initialized anywhere so I think it should be deleted but is used here: 360 *presource = Z_RES(zsession);

The only initialization of zsession is commented out here:

467 //TODO Sean-Der
468 //ZEND_REGISTER_RESOURCE(&zsession, session, le_ssh2_session);
remicollet commented 3 years ago

I agree, there is something terribly wrong with this var.

BTW I was not able to reproduce the segfault (even with a new test for auth failure, which I haven't committed in my PR, as very long because of timeout)

qjavax commented 3 years ago

This bug is only present in php 7.4+, and is possible to reproduce like this: https://bugs.php.net/bug.php?id=79757, Example from gdb before patching:

(gdb) r ssh2.php
Starting program: /usr/bin/php ssh2.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000055555580da34 in zend_list_delete ()
(gdb) bt full
#0  0x000055555580da34 in zend_list_delete ()
No symbol table info available.
#1  0x00007ffff44df1db in php_ssh2_sftp_stream_close (stream=<optimized out>, 
    close_handle=<optimized out>)
    at /home/EDITED/repos/pecl-networking-ssh2/ssh2_sftp.c:139
        data = 0x7ffff5480060
#2  0x00005555557afc64 in _php_stream_free ()
No symbol table info available.

and after:

(gdb) r ssh2.php
Starting program: /usr/bin/php ssh2.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
PHP Warning:  file_get_contents(ssh2.sftp://EDITED/upload/test.txt): failed to open stream: operation failed in /home/EDITED/repos/pecl-networking-ssh2/ssh2.php on line 9
[Inferior 1 (process 13717) exited normally]
(gdb) 

content of tested php code:

<?php
$options = [
    "ssh2" => [
        "username" => "EDITED",
        "password" => 'EDITED'
    ]
];
$context = stream_context_create($options, []);
file_get_contents('ssh2.sftp://EDITED/upload/test.txt', false, $context);

I'm using Ubuntu 20.04 and php 7.4.3