mirror of
https://github.com/php/pecl-networking-ssh2.git
synced 2026-03-23 22:52:06 +01:00
BUG_73819: call ssh2_shell() causes segment fault
1. php_ssh2_shell_open() was calling zend_hash_get_current_key_ex 2. php_ssh2_exec_command() / php_ssh2_shell_open() / php_ssh2_direct_tcpip() were being passed a pointer instead of the resource ID. 3. Renamed session_rsrc to session_rsrcid 3. Added test for ssh2_shell and reading / writing to the stream
This commit is contained in:
committed by
Casper Langemeijer
parent
756e2f1369
commit
62d00b340f
@@ -118,8 +118,8 @@ typedef struct _php_ssh2_channel_data {
|
||||
char is_blocking;
|
||||
long timeout;
|
||||
|
||||
/* Resource ID, zend_list_addref() when opening, zend_list_delete() when closing */
|
||||
long session_rsrc;
|
||||
/* Resource ID */
|
||||
int session_rsrcid;
|
||||
|
||||
/* Allow one stream to be closed while the other is kept open */
|
||||
unsigned char *refcount;
|
||||
|
||||
6
ssh2.c
6
ssh2.c
@@ -810,7 +810,7 @@ PHP_FUNCTION(ssh2_forward_accept)
|
||||
channel_data->channel = channel;
|
||||
channel_data->streamid = 0;
|
||||
channel_data->is_blocking = 0;
|
||||
channel_data->session_rsrc = data->session_rsrcid;
|
||||
channel_data->session_rsrcid = data->session_rsrcid;
|
||||
channel_data->refcount = NULL;
|
||||
|
||||
stream = php_stream_alloc(&php_ssh2_channel_stream_ops, channel_data, 0, "r+");
|
||||
@@ -821,7 +821,7 @@ PHP_FUNCTION(ssh2_forward_accept)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
//TODO Sean-Der
|
||||
//zend_list_addref(channel_data->session_rsrc);
|
||||
//zend_list_addref(channel_data->session_rsrcid);
|
||||
|
||||
php_stream_to_zval(stream, return_value);
|
||||
}
|
||||
@@ -975,7 +975,7 @@ PHP_FUNCTION(ssh2_publickey_init)
|
||||
|
||||
data = emalloc(sizeof(php_ssh2_pkey_subsys_data));
|
||||
data->session = session;
|
||||
data->session_rsrcid = Z_LVAL_P(zsession);
|
||||
data->session_rsrcid = Z_RES_P(zsession)->handle;
|
||||
//TODO Sean-Der
|
||||
//zend_list_addref(data->session_rsrcid);
|
||||
data->pkey = pkey;
|
||||
|
||||
@@ -50,7 +50,7 @@ static size_t php_ssh2_channel_stream_write(php_stream *stream, const char *buf,
|
||||
zval *zresource;
|
||||
|
||||
libssh2_channel_set_blocking(abstract->channel, abstract->is_blocking);
|
||||
zresource = php_ssh2_zval_from_resource_handle(abstract->session_rsrc);
|
||||
zresource = php_ssh2_zval_from_resource_handle(abstract->session_rsrcid);
|
||||
session = (LIBSSH2_SESSION *)zend_fetch_resource(Z_RES_P(zresource), PHP_SSH2_SESSION_RES_NAME, le_ssh2_session);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ static size_t php_ssh2_channel_stream_read(php_stream *stream, char *buf, size_t
|
||||
|
||||
stream->eof = libssh2_channel_eof(abstract->channel);
|
||||
libssh2_channel_set_blocking(abstract->channel, abstract->is_blocking);
|
||||
zresource = php_ssh2_zval_from_resource_handle(abstract->session_rsrc);
|
||||
zresource = php_ssh2_zval_from_resource_handle(abstract->session_rsrcid);
|
||||
session = (LIBSSH2_SESSION *)zend_fetch_resource(Z_RES_P(zresource), PHP_SSH2_SESSION_RES_NAME, le_ssh2_session);
|
||||
|
||||
#ifdef PHP_SSH2_SESSION_TIMEOUT
|
||||
@@ -138,7 +138,7 @@ static int php_ssh2_channel_stream_close(php_stream *stream, int close_handle)
|
||||
libssh2_channel_eof(abstract->channel);
|
||||
libssh2_channel_free(abstract->channel);
|
||||
//TODO Sean-Der
|
||||
//zend_list_delete(abstract->session_rsrc);
|
||||
//zend_list_delete(abstract->session_rsrcid);
|
||||
}
|
||||
efree(abstract);
|
||||
|
||||
@@ -516,7 +516,7 @@ static php_stream *php_ssh2_shell_open(LIBSSH2_SESSION *session, int resource_id
|
||||
zend_ulong idx;
|
||||
|
||||
for(zend_hash_internal_pointer_reset(HASH_OF(environment));
|
||||
(key_type = zend_hash_get_current_key_ex(HASH_OF(environment), &key, &idx, NULL)) != HASH_KEY_NON_EXISTENT;
|
||||
(key_type = zend_hash_get_current_key(HASH_OF(environment), &key, &idx)) != HASH_KEY_NON_EXISTENT;
|
||||
zend_hash_move_forward(HASH_OF(environment))) {
|
||||
if (key_type == HASH_KEY_IS_STRING) {
|
||||
zval *value;
|
||||
@@ -563,7 +563,7 @@ static php_stream *php_ssh2_shell_open(LIBSSH2_SESSION *session, int resource_id
|
||||
channel_data->streamid = 0;
|
||||
channel_data->is_blocking = 0;
|
||||
channel_data->timeout = 0;
|
||||
channel_data->session_rsrc = resource_id;
|
||||
channel_data->session_rsrcid = resource_id;
|
||||
channel_data->refcount = NULL;
|
||||
|
||||
stream = php_stream_alloc(&php_ssh2_channel_stream_ops, channel_data, 0, "r+");
|
||||
@@ -715,7 +715,7 @@ PHP_FUNCTION(ssh2_shell)
|
||||
|
||||
SSH2_FETCH_AUTHENTICATED_SESSION(session, zsession);
|
||||
|
||||
stream = php_ssh2_shell_open(session, Z_LVAL_P(zsession), term, term_len, environment, width, height, type);
|
||||
stream = php_ssh2_shell_open(session, Z_RES_P(zsession)->handle, term, term_len, environment, width, height, type);
|
||||
if (!stream) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -804,7 +804,7 @@ static php_stream *php_ssh2_exec_command(LIBSSH2_SESSION *session, int resource_
|
||||
channel_data->streamid = 0;
|
||||
channel_data->is_blocking = 0;
|
||||
channel_data->timeout = 0;
|
||||
channel_data->session_rsrc = resource_id;
|
||||
channel_data->session_rsrcid = resource_id;
|
||||
channel_data->refcount = NULL;
|
||||
|
||||
stream = php_stream_alloc(&php_ssh2_channel_stream_ops, channel_data, 0, "r+");
|
||||
@@ -948,7 +948,7 @@ PHP_FUNCTION(ssh2_exec)
|
||||
|
||||
SSH2_FETCH_AUTHENTICATED_SESSION(session, zsession);
|
||||
|
||||
stream = php_ssh2_exec_command(session, Z_LVAL_P(zsession), command, term, term_len, environment, width, height, type);
|
||||
stream = php_ssh2_exec_command(session, Z_RES_P(zsession)->handle, command, term, term_len, environment, width, height, type);
|
||||
if (!stream) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -987,7 +987,7 @@ static php_stream *php_ssh2_scp_xfer(LIBSSH2_SESSION *session, int resource_id,
|
||||
channel_data->streamid = 0;
|
||||
channel_data->is_blocking = 0;
|
||||
channel_data->timeout = 0;
|
||||
channel_data->session_rsrc = resource_id;
|
||||
channel_data->session_rsrcid = resource_id;
|
||||
channel_data->refcount = NULL;
|
||||
|
||||
stream = php_stream_alloc(&php_ssh2_channel_stream_ops, channel_data, 0, "r");
|
||||
@@ -1236,7 +1236,7 @@ static php_stream *php_ssh2_direct_tcpip(LIBSSH2_SESSION *session, int resource_
|
||||
channel_data->streamid = 0;
|
||||
channel_data->is_blocking = 0;
|
||||
channel_data->timeout = 0;
|
||||
channel_data->session_rsrc = resource_id;
|
||||
channel_data->session_rsrcid = resource_id;
|
||||
channel_data->refcount = NULL;
|
||||
|
||||
stream = php_stream_alloc(&php_ssh2_channel_stream_ops, channel_data, 0, "r+");
|
||||
@@ -1337,7 +1337,7 @@ PHP_FUNCTION(ssh2_tunnel)
|
||||
|
||||
SSH2_FETCH_AUTHENTICATED_SESSION(session, zsession);
|
||||
|
||||
stream = php_ssh2_direct_tcpip(session, Z_LVAL_P(zsession), host, port);
|
||||
stream = php_ssh2_direct_tcpip(session, Z_RES_P(zsession)->handle, host, port);
|
||||
if (!stream) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
24
tests/ssh2_shell.phpt
Normal file
24
tests/ssh2_shell.phpt
Normal file
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
ssh2_shell_test() - Tests opening a shell
|
||||
--SKIPIF--
|
||||
<?php require('ssh2_skip.inc'); ssh2t_needs_auth(); ?>
|
||||
--FILE--
|
||||
<?php require('ssh2_test.inc');
|
||||
|
||||
$ssh = ssh2_connect(TEST_SSH2_HOSTNAME, TEST_SSH2_PORT);
|
||||
var_dump(ssh2t_auth($ssh));
|
||||
$shell = ssh2_shell($ssh);
|
||||
var_dump($shell);
|
||||
|
||||
fwrite( $shell, 'echo "foo bar"'.PHP_EOL);
|
||||
sleep(1);
|
||||
while($line = fgets($shell)) {
|
||||
echo $line;
|
||||
}
|
||||
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
resource(%d) of type (stream)
|
||||
%a
|
||||
foo bar
|
||||
%a
|
||||
Reference in New Issue
Block a user