From 3893140b1ff88d70407d5ab902022ab36d7305d7 Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Mon, 23 Mar 2015 22:47:46 +0100 Subject: [PATCH 1/5] scp.c: fix that scp_send may transmit not initialised memory Fixes ticket 244. Thanks Torsten. Upstream-commit: b99204f2896b0cdafa3ecc0736f0252ce44c32c7 Signed-off-by: Kamil Dudka --- src/scp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/scp.c b/src/scp.c index 63d181e..2f92804 100644 --- a/src/scp.c +++ b/src/scp.c @@ -801,12 +801,18 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode, cmd_len = strlen((char *)session->scpSend_command); + memset(&session->scpSend_command[cmd_len], 0, + session->scpSend_command_len - cmd_len); + (void)shell_quotearg(path, &session->scpSend_command[cmd_len], session->scpSend_command_len - cmd_len); session->scpSend_command[session->scpSend_command_len - 1] = '\0'; + session->scpSend_command_len = + strlen((char *)session->scpSend_command); + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Opening channel for SCP send"); /* Allocate a channel */ -- 2.13.5 From 2ecb8c5d6e116fcc71a31360115c9c2b4b0ca1d2 Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Mon, 23 Mar 2015 23:04:24 +0100 Subject: [PATCH 2/5] scp.c: fix that scp_recv may transmit not initialised memory Upstream-commit: 1e7988cb0d8dae32148b04dd93e919a770599f30 Signed-off-by: Kamil Dudka --- src/scp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/scp.c b/src/scp.c index 2f92804..d0c0d26 100644 --- a/src/scp.c +++ b/src/scp.c @@ -299,10 +299,17 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb) cmd_len = strlen((char *)session->scpRecv_command); + memset(&session->scpRecv_command[cmd_len], 0, + session->scpRecv_command_len - cmd_len); + (void) shell_quotearg(path, &session->scpRecv_command[cmd_len], session->scpRecv_command_len - cmd_len); + session->scpRecv_command[session->scpRecv_command_len - 1] = '\0'; + + session->scpRecv_command_len = + strlen((char *)session->scpRecv_command); _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Opening channel for SCP receive"); -- 2.13.5 From 5b23e9e9875302791f5c190cf0e4f61fd9879ff0 Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Mon, 23 Mar 2015 23:05:41 +0100 Subject: [PATCH 3/5] scp.c: improved and streamlined formatting Upstream-commit: 2d59b41daa3925645a26e6406fc318e6c2bfaae6 Signed-off-by: Kamil Dudka --- src/scp.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/scp.c b/src/scp.c index d0c0d26..30d46af 100644 --- a/src/scp.c +++ b/src/scp.c @@ -295,16 +295,17 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb) } snprintf((char *)session->scpRecv_command, - session->scpRecv_command_len, "scp -%sf ", sb?"p":""); + session->scpRecv_command_len, + "scp -%sf ", sb?"p":""); cmd_len = strlen((char *)session->scpRecv_command); memset(&session->scpRecv_command[cmd_len], 0, session->scpRecv_command_len - cmd_len); - (void) shell_quotearg(path, - &session->scpRecv_command[cmd_len], - session->scpRecv_command_len - cmd_len); + (void)shell_quotearg(path, + &session->scpRecv_command[cmd_len], + session->scpRecv_command_len - cmd_len); session->scpRecv_command[session->scpRecv_command_len - 1] = '\0'; @@ -797,13 +798,16 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode, session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len); + if (!session->scpSend_command) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate a command buffer for scp session"); + "Unable to allocate a command buffer for " + "SCP session"); return NULL; } - snprintf((char *)session->scpSend_command, session->scpSend_command_len, + snprintf((char *)session->scpSend_command, + session->scpSend_command_len, "scp -%st ", (mtime || atime)?"p":""); cmd_len = strlen((char *)session->scpSend_command); -- 2.13.5 From fc0d9df034e8701cdcf6c24fd40b1dbc8bc3e084 Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Mon, 23 Mar 2015 23:17:31 +0100 Subject: [PATCH 4/5] scp.c: improved command length calculation Reduced number of calls to strlen, because shell_quotearg already returns the length of the resulting string (e.q. quoted path) which we can add to the existing and known cmd_len. Removed obsolete call to memset again, because we can put a final NULL-byte at the end of the string using the calculated length. Upstream-commit: 3d3347c0625ce29b5581a0aa45e6e3be580769f1 Signed-off-by: Kamil Dudka --- src/scp.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/scp.c b/src/scp.c index 30d46af..f3d4995 100644 --- a/src/scp.c +++ b/src/scp.c @@ -299,18 +299,12 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb) "scp -%sf ", sb?"p":""); cmd_len = strlen((char *)session->scpRecv_command); + cmd_len += shell_quotearg(path, + &session->scpRecv_command[cmd_len], + session->scpRecv_command_len - cmd_len); - memset(&session->scpRecv_command[cmd_len], 0, - session->scpRecv_command_len - cmd_len); - - (void)shell_quotearg(path, - &session->scpRecv_command[cmd_len], - session->scpRecv_command_len - cmd_len); - - session->scpRecv_command[session->scpRecv_command_len - 1] = '\0'; - - session->scpRecv_command_len = - strlen((char *)session->scpRecv_command); + session->scpRecv_command[cmd_len] = '\0'; + session->scpRecv_command_len = cmd_len + 1; _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Opening channel for SCP receive"); @@ -811,18 +805,12 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode, "scp -%st ", (mtime || atime)?"p":""); cmd_len = strlen((char *)session->scpSend_command); + cmd_len += shell_quotearg(path, + &session->scpSend_command[cmd_len], + session->scpSend_command_len - cmd_len); - memset(&session->scpSend_command[cmd_len], 0, - session->scpSend_command_len - cmd_len); - - (void)shell_quotearg(path, - &session->scpSend_command[cmd_len], - session->scpSend_command_len - cmd_len); - - session->scpSend_command[session->scpSend_command_len - 1] = '\0'; - - session->scpSend_command_len = - strlen((char *)session->scpSend_command); + session->scpSend_command[cmd_len] = '\0'; + session->scpSend_command_len = cmd_len + 1; _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Opening channel for SCP send"); -- 2.13.5 From 9506e299fa5116aa8c4c626e6de1feaed9ff9ff8 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Sep 2017 21:13:45 +0200 Subject: [PATCH 5/5] scp: do not NUL-terminate the command for remote exec (#208) It breaks SCP download/upload from/to certain server implementations. The bug does not manifest with OpenSSH, which silently drops the NUL byte (eventually with any garbage that follows the NUL byte) before executing it. Bug: https://bugzilla.redhat.com/1489736 Upstream-commit: 819ef4f2037490b6aa2e870aea851b6364184090 Signed-off-by: Kamil Dudka --- src/scp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scp.c b/src/scp.c index f3d4995..c6451bc 100644 --- a/src/scp.c +++ b/src/scp.c @@ -303,8 +303,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb) &session->scpRecv_command[cmd_len], session->scpRecv_command_len - cmd_len); - session->scpRecv_command[cmd_len] = '\0'; - session->scpRecv_command_len = cmd_len + 1; + /* the command to exec should _not_ be NUL-terminated */ + session->scpRecv_command_len = cmd_len; _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Opening channel for SCP receive"); @@ -809,8 +809,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode, &session->scpSend_command[cmd_len], session->scpSend_command_len - cmd_len); - session->scpSend_command[cmd_len] = '\0'; - session->scpSend_command_len = cmd_len + 1; + /* the command to exec should _not_ be NUL-terminated */ + session->scpSend_command_len = cmd_len; _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Opening channel for SCP send"); -- 2.13.5