fix cve
This commit is contained in:
parent
143d5bab4e
commit
195f44605a
1390
0001-CVE-2019-14889.patch
Normal file
1390
0001-CVE-2019-14889.patch
Normal file
File diff suppressed because it is too large
Load Diff
169
0002-CVE-2019-14889.patch
Normal file
169
0002-CVE-2019-14889.patch
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
From 82c375b7c99141a5495e62060e0b7f9c97981e7e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||||
|
Date: Fri, 25 Oct 2019 13:24:28 +0200
|
||||||
|
Subject: CVE-2019-14889: scp: Log SCP warnings received from the server
|
||||||
|
|
||||||
|
Fixes T181
|
||||||
|
|
||||||
|
Previously, warnings received from the server were ignored. With this
|
||||||
|
change the warning message sent by the server will be logged.
|
||||||
|
|
||||||
|
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||||
|
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
(cherry picked from commit c75d417d06867fd792b788e6281334621c2cd335)
|
||||||
|
---
|
||||||
|
src/scp.c | 75 ++++++++++-----------------------------------------------------
|
||||||
|
1 file changed, 11 insertions(+), 64 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/scp.c b/src/scp.c
|
||||||
|
index 5de0e6ff..166f3d2f 100644
|
||||||
|
--- a/src/scp.c
|
||||||
|
+++ b/src/scp.c
|
||||||
|
@@ -113,7 +113,6 @@ int ssh_scp_init(ssh_scp scp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char execbuffer[1024] = {0};
|
||||||
|
- uint8_t code;
|
||||||
|
|
||||||
|
if (scp == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
@@ -157,19 +156,8 @@ int ssh_scp_init(ssh_scp scp)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scp->mode == SSH_SCP_WRITE) {
|
||||||
|
- rc = ssh_channel_read(scp->channel, &code, 1, 0);
|
||||||
|
- if (rc <= 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
- "Error reading status code: %s",
|
||||||
|
- ssh_get_error(scp->session));
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
- return SSH_ERROR;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (code != 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
- "scp status code %ud not valid", code);
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
+ rc = ssh_scp_response(scp, NULL);
|
||||||
|
+ if (rc != 0) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@@ -277,7 +265,6 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode)
|
||||||
|
{
|
||||||
|
char buffer[1024] = {0};
|
||||||
|
int rc;
|
||||||
|
- uint8_t code;
|
||||||
|
char *dir = NULL;
|
||||||
|
char *perms = NULL;
|
||||||
|
|
||||||
|
@@ -303,19 +290,8 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode)
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
- rc = ssh_channel_read(scp->channel, &code, 1, 0);
|
||||||
|
- if (rc <= 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
- "Error reading status code: %s",
|
||||||
|
- ssh_get_error(scp->session));
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
- return SSH_ERROR;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (code != 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL, "scp status code %ud not valid",
|
||||||
|
- code);
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
+ rc = ssh_scp_response(scp, NULL);
|
||||||
|
+ if (rc != 0) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -334,7 +310,6 @@ int ssh_scp_leave_directory(ssh_scp scp)
|
||||||
|
{
|
||||||
|
char buffer[] = "E\n";
|
||||||
|
int rc;
|
||||||
|
- uint8_t code;
|
||||||
|
|
||||||
|
if (scp == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
@@ -352,18 +327,8 @@ int ssh_scp_leave_directory(ssh_scp scp)
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
- rc = ssh_channel_read(scp->channel, &code, 1, 0);
|
||||||
|
- if (rc <= 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL, "Error reading status code: %s",
|
||||||
|
- ssh_get_error(scp->session));
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
- return SSH_ERROR;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (code != 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL, "scp status code %ud not valid",
|
||||||
|
- code);
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
+ rc = ssh_scp_response(scp, NULL);
|
||||||
|
+ if (rc != 0) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -395,7 +360,6 @@ int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size,
|
||||||
|
int rc;
|
||||||
|
char *file = NULL;
|
||||||
|
char *perms = NULL;
|
||||||
|
- uint8_t code;
|
||||||
|
|
||||||
|
if (scp == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
@@ -422,19 +386,8 @@ int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size,
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
- rc = ssh_channel_read(scp->channel, &code, 1, 0);
|
||||||
|
- if (rc <= 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
- "Error reading status code: %s",
|
||||||
|
- ssh_get_error(scp->session));
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
- return SSH_ERROR;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (code != 0) {
|
||||||
|
- ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
- "scp status code %ud not valid", code);
|
||||||
|
- scp->state = SSH_SCP_ERROR;
|
||||||
|
+ rc = ssh_scp_response(scp, NULL);
|
||||||
|
+ if (rc != 0) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -498,7 +451,7 @@ int ssh_scp_response(ssh_scp scp, char **response)
|
||||||
|
|
||||||
|
if (code > 2) {
|
||||||
|
ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
- "SCP: invalid status code %ud received", code);
|
||||||
|
+ "SCP: invalid status code %u received", code);
|
||||||
|
scp->state = SSH_SCP_ERROR;
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
@@ -585,14 +538,8 @@ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len)
|
||||||
|
* and handle */
|
||||||
|
rc = ssh_channel_poll(scp->channel, 0);
|
||||||
|
if (rc > 0) {
|
||||||
|
- rc = ssh_channel_read(scp->channel, &code, 1, 0);
|
||||||
|
- if (rc == SSH_ERROR) {
|
||||||
|
- return SSH_ERROR;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (code == 1 || code == 2) {
|
||||||
|
- ssh_set_error(scp->session, SSH_REQUEST_DENIED,
|
||||||
|
- "SCP: Error: status code %i received", code);
|
||||||
|
+ rc = ssh_scp_response(scp, NULL);
|
||||||
|
+ if (rc != 0) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
cgit v1.2.1
|
||||||
|
|
||||||
238
0003-CVE-2019-14889.patch
Normal file
238
0003-CVE-2019-14889.patch
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
From 2ba1dea5493fb2f5a5be2dd263ce46ccb5f8ec76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||||
|
Date: Tue, 22 Oct 2019 16:08:24 +0200
|
||||||
|
Subject: CVE-2019-14889: misc: Add function to quote file names
|
||||||
|
|
||||||
|
The added function quote file names strings to be used in a shell.
|
||||||
|
Special cases are treated for the charactes '\'' and '!'.
|
||||||
|
|
||||||
|
Fixes T181
|
||||||
|
|
||||||
|
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||||
|
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
(cherry picked from commit c4ad1aba9860e02fe03ef3f58a047964e9e765fc)
|
||||||
|
---
|
||||||
|
include/libssh/misc.h | 8 +++
|
||||||
|
src/misc.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 192 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/include/libssh/misc.h b/include/libssh/misc.h
|
||||||
|
index bc50cff8..0531d4f3 100644
|
||||||
|
--- a/include/libssh/misc.h
|
||||||
|
+++ b/include/libssh/misc.h
|
||||||
|
@@ -50,6 +50,12 @@ struct ssh_timestamp {
|
||||||
|
long useconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
+enum ssh_quote_state_e {
|
||||||
|
+ NO_QUOTE,
|
||||||
|
+ SINGLE_QUOTE,
|
||||||
|
+ DOUBLE_QUOTE
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct ssh_list *ssh_list_new(void);
|
||||||
|
void ssh_list_free(struct ssh_list *list);
|
||||||
|
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
|
||||||
|
@@ -81,4 +87,6 @@ int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
|
||||||
|
|
||||||
|
int ssh_match_group(const char *group, const char *object);
|
||||||
|
|
||||||
|
+int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
|
||||||
|
+
|
||||||
|
#endif /* MISC_H_ */
|
||||||
|
diff --git a/src/misc.c b/src/misc.c
|
||||||
|
index 18c9745e..b042b46d 100644
|
||||||
|
--- a/src/misc.c
|
||||||
|
+++ b/src/misc.c
|
||||||
|
@@ -1108,4 +1108,188 @@ char *strndup(const char *s, size_t n)
|
||||||
|
}
|
||||||
|
#endif /* ! HAVE_STRNDUP */
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * @internal
|
||||||
|
+ *
|
||||||
|
+ * @brief Quote file name to be used on shell.
|
||||||
|
+ *
|
||||||
|
+ * Try to put the given file name between single quotes. There are special
|
||||||
|
+ * cases:
|
||||||
|
+ *
|
||||||
|
+ * - When the '\'' char is found in the file name, it is double quoted
|
||||||
|
+ * - example:
|
||||||
|
+ * input: a'b
|
||||||
|
+ * output: 'a'"'"'b'
|
||||||
|
+ * - When the '!' char is found in the file name, it is replaced by an unquoted
|
||||||
|
+ * verbatim char "\!"
|
||||||
|
+ * - example:
|
||||||
|
+ * input: a!b
|
||||||
|
+ * output 'a'\!'b'
|
||||||
|
+ *
|
||||||
|
+ * @param[in] file_name File name string to be quoted before used on shell
|
||||||
|
+ * @param[out] buf Buffer to receive the final quoted file name. Must
|
||||||
|
+ * have room for the final quoted string. The maximum
|
||||||
|
+ * output length would be (3 * strlen(file_name) + 1)
|
||||||
|
+ * since in the worst case each character would be
|
||||||
|
+ * replaced by 3 characters, plus the terminating '\0'.
|
||||||
|
+ * @param[in] buf_len The size of the provided output buffer
|
||||||
|
+ *
|
||||||
|
+ * @returns SSH_ERROR on error; length of the resulting string not counting the
|
||||||
|
+ * string terminator '\0'
|
||||||
|
+ * */
|
||||||
|
+int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len)
|
||||||
|
+{
|
||||||
|
+ const char *src = NULL;
|
||||||
|
+ char *dst = NULL;
|
||||||
|
+ size_t required_buf_len;
|
||||||
|
+
|
||||||
|
+ enum ssh_quote_state_e state = NO_QUOTE;
|
||||||
|
+
|
||||||
|
+ if (file_name == NULL || buf == NULL || buf_len == 0) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "Invalid parameter");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Only allow file names smaller than 32kb. */
|
||||||
|
+ if (strlen(file_name) > 32 * 1024) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "File name too long");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Paranoia check */
|
||||||
|
+ required_buf_len = (size_t)3 * strlen(file_name) + 1;
|
||||||
|
+ if (required_buf_len > buf_len) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "Buffer too small");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ src = file_name;
|
||||||
|
+ dst = buf;
|
||||||
|
+
|
||||||
|
+ while ((*src != '\0')) {
|
||||||
|
+ switch (*src) {
|
||||||
|
+
|
||||||
|
+ /* The '\'' char is double quoted */
|
||||||
|
+
|
||||||
|
+ case '\'':
|
||||||
|
+ switch (state) {
|
||||||
|
+ case NO_QUOTE:
|
||||||
|
+ /* Start a new double quoted string. The '\'' char will be
|
||||||
|
+ * copied to the beginning of it at the end of the loop. */
|
||||||
|
+ *dst++ = '"';
|
||||||
|
+ break;
|
||||||
|
+ case SINGLE_QUOTE:
|
||||||
|
+ /* Close the current single quoted string and start a new double
|
||||||
|
+ * quoted string. The '\'' char will be copied to the beginning
|
||||||
|
+ * of it at the end of the loop. */
|
||||||
|
+ *dst++ = '\'';
|
||||||
|
+ *dst++ = '"';
|
||||||
|
+ break;
|
||||||
|
+ case DOUBLE_QUOTE:
|
||||||
|
+ /* If already in the double quoted string, keep copying the
|
||||||
|
+ * sequence of chars. */
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ /* Should never be reached */
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* When the '\'' char is found, the resulting state will be
|
||||||
|
+ * DOUBLE_QUOTE in any case*/
|
||||||
|
+ state = DOUBLE_QUOTE;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ /* The '!' char is replaced by unquoted "\!" */
|
||||||
|
+
|
||||||
|
+ case '!':
|
||||||
|
+ switch (state) {
|
||||||
|
+ case NO_QUOTE:
|
||||||
|
+ /* The '!' char is interpreted in some shells (e.g. CSH) even
|
||||||
|
+ * when is quoted with single quotes. Replace it with unquoted
|
||||||
|
+ * "\!" which is correctly interpreted as the '!' character. */
|
||||||
|
+ *dst++ = '\\';
|
||||||
|
+ break;
|
||||||
|
+ case SINGLE_QUOTE:
|
||||||
|
+ /* Close the current quoted string and replace '!' for unquoted
|
||||||
|
+ * "\!" */
|
||||||
|
+ *dst++ = '\'';
|
||||||
|
+ *dst++ = '\\';
|
||||||
|
+ break;
|
||||||
|
+ case DOUBLE_QUOTE:
|
||||||
|
+ /* Close current quoted string and replace "!" for unquoted
|
||||||
|
+ * "\!" */
|
||||||
|
+ *dst++ = '"';
|
||||||
|
+ *dst++ = '\\';
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ /* Should never be reached */
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* When the '!' char is found, the resulting state will be NO_QUOTE
|
||||||
|
+ * in any case*/
|
||||||
|
+ state = NO_QUOTE;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ /* Ordinary chars are single quoted */
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ switch (state) {
|
||||||
|
+ case NO_QUOTE:
|
||||||
|
+ /* Start a new single quoted string */
|
||||||
|
+ *dst++ = '\'';
|
||||||
|
+ break;
|
||||||
|
+ case SINGLE_QUOTE:
|
||||||
|
+ /* If already in the single quoted string, keep copying the
|
||||||
|
+ * sequence of chars. */
|
||||||
|
+ break;
|
||||||
|
+ case DOUBLE_QUOTE:
|
||||||
|
+ /* Close current double quoted string and start a new single
|
||||||
|
+ * quoted string. */
|
||||||
|
+ *dst++ = '"';
|
||||||
|
+ *dst++ = '\'';
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ /* Should never be reached */
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* When an ordinary char is found, the resulting state will be
|
||||||
|
+ * SINGLE_QUOTE in any case*/
|
||||||
|
+ state = SINGLE_QUOTE;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Copy the current char to output */
|
||||||
|
+ *dst++ = *src++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Close the quoted string when necessary */
|
||||||
|
+
|
||||||
|
+ switch (state) {
|
||||||
|
+ case NO_QUOTE:
|
||||||
|
+ /* No open string */
|
||||||
|
+ break;
|
||||||
|
+ case SINGLE_QUOTE:
|
||||||
|
+ /* Close current single quoted string */
|
||||||
|
+ *dst++ = '\'';
|
||||||
|
+ break;
|
||||||
|
+ case DOUBLE_QUOTE:
|
||||||
|
+ /* Close current double quoted string */
|
||||||
|
+ *dst++ = '"';
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ /* Should never be reached */
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Put the string terminator */
|
||||||
|
+ *dst = '\0';
|
||||||
|
+
|
||||||
|
+ return dst - buf;
|
||||||
|
+
|
||||||
|
+error:
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/** @} */
|
||||||
|
--
|
||||||
|
cgit v1.2.1
|
||||||
|
|
||||||
33
0004-CVE-2019-14889.patch
Normal file
33
0004-CVE-2019-14889.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From 391c78de9d0f7baec3a44d86a76f4e1324eb9529 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
Date: Fri, 6 Dec 2019 09:40:30 +0100
|
||||||
|
Subject: CVE-2019-14889: scp: Don't allow file path longer than 32kb
|
||||||
|
|
||||||
|
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
(cherry picked from commit 0b5ee397260b6e08dffa2c1ce515a153aaeda765)
|
||||||
|
---
|
||||||
|
src/scp.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/scp.c b/src/scp.c
|
||||||
|
index 166f3d2f..4b00aa5f 100644
|
||||||
|
--- a/src/scp.c
|
||||||
|
+++ b/src/scp.c
|
||||||
|
@@ -80,6 +80,12 @@ ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (strlen(location) > 32 * 1024) {
|
||||||
|
+ ssh_set_error(session, SSH_FATAL,
|
||||||
|
+ "Location path is too long");
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
scp->location = strdup(location);
|
||||||
|
if (scp->location == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
--
|
||||||
|
cgit v1.2.1
|
||||||
|
|
||||||
|
|
||||||
128
0005-CVE-2019-14889.patch
Normal file
128
0005-CVE-2019-14889.patch
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
From b0edec4e8d01ad73b0d26ad4070d7e1a1e86dfc8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||||
|
Date: Thu, 31 Oct 2019 18:10:27 +0100
|
||||||
|
Subject: CVE-2019-14889: scp: Quote location to be used on shell
|
||||||
|
|
||||||
|
Single quote file paths to be used on commands to be executed on remote
|
||||||
|
shell.
|
||||||
|
|
||||||
|
Fixes T181
|
||||||
|
|
||||||
|
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
||||||
|
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
(cherry picked from commit 3830c7ae6eec751b7618d3fc159cb5bb3c8806a6)
|
||||||
|
---
|
||||||
|
src/scp.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 56 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/scp.c b/src/scp.c
|
||||||
|
index 4b00aa5f..652551e3 100644
|
||||||
|
--- a/src/scp.c
|
||||||
|
+++ b/src/scp.c
|
||||||
|
@@ -29,6 +29,7 @@
|
||||||
|
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
#include "libssh/scp.h"
|
||||||
|
+#include "libssh/misc.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup libssh_scp The SSH scp functions
|
||||||
|
@@ -119,6 +120,9 @@ int ssh_scp_init(ssh_scp scp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char execbuffer[1024] = {0};
|
||||||
|
+ char *quoted_location = NULL;
|
||||||
|
+ size_t quoted_location_len = 0;
|
||||||
|
+ size_t scp_location_len;
|
||||||
|
|
||||||
|
if (scp == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
@@ -130,33 +134,79 @@ int ssh_scp_init(ssh_scp scp)
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
- SSH_LOG(SSH_LOG_PROTOCOL,
|
||||||
|
- "Initializing scp session %s %son location '%s'",
|
||||||
|
+ if (scp->location == NULL) {
|
||||||
|
+ ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
+ "Invalid scp context: location is NULL");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SSH_LOG(SSH_LOG_PROTOCOL, "Initializing scp session %s %son location '%s'",
|
||||||
|
scp->mode == SSH_SCP_WRITE?"write":"read",
|
||||||
|
- scp->recursive?"recursive ":"",
|
||||||
|
+ scp->recursive ? "recursive " : "",
|
||||||
|
scp->location);
|
||||||
|
|
||||||
|
scp->channel = ssh_channel_new(scp->session);
|
||||||
|
if (scp->channel == NULL) {
|
||||||
|
+ ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
+ "Channel creation failed for scp");
|
||||||
|
scp->state = SSH_SCP_ERROR;
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_channel_open_session(scp->channel);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
+ ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
+ "Failed to open channel for scp");
|
||||||
|
+ scp->state = SSH_SCP_ERROR;
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* In the worst case, each character would be replaced by 3 plus the string
|
||||||
|
+ * terminator '\0' */
|
||||||
|
+ scp_location_len = strlen(scp->location);
|
||||||
|
+ quoted_location_len = ((size_t)3 * scp_location_len) + 1;
|
||||||
|
+ /* Paranoia check */
|
||||||
|
+ if (quoted_location_len < scp_location_len) {
|
||||||
|
+ ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
+ "Buffer overflow detected");
|
||||||
|
+ scp->state = SSH_SCP_ERROR;
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ quoted_location = (char *)calloc(1, quoted_location_len);
|
||||||
|
+ if (quoted_location == NULL) {
|
||||||
|
+ ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
+ "Failed to allocate memory for quoted location");
|
||||||
|
+ scp->state = SSH_SCP_ERROR;
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = ssh_quote_file_name(scp->location, quoted_location,
|
||||||
|
+ quoted_location_len);
|
||||||
|
+ if (rc <= 0) {
|
||||||
|
+ ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
+ "Failed to single quote command location");
|
||||||
|
+ SAFE_FREE(quoted_location);
|
||||||
|
scp->state = SSH_SCP_ERROR;
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scp->mode == SSH_SCP_WRITE) {
|
||||||
|
snprintf(execbuffer, sizeof(execbuffer), "scp -t %s %s",
|
||||||
|
- scp->recursive ? "-r":"", scp->location);
|
||||||
|
+ scp->recursive ? "-r" : "", quoted_location);
|
||||||
|
} else {
|
||||||
|
snprintf(execbuffer, sizeof(execbuffer), "scp -f %s %s",
|
||||||
|
- scp->recursive ? "-r":"", scp->location);
|
||||||
|
+ scp->recursive ? "-r" : "", quoted_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (ssh_channel_request_exec(scp->channel, execbuffer) == SSH_ERROR) {
|
||||||
|
+ SAFE_FREE(quoted_location);
|
||||||
|
+
|
||||||
|
+ SSH_LOG(SSH_LOG_DEBUG, "Executing command: %s", execbuffer);
|
||||||
|
+
|
||||||
|
+ rc = ssh_channel_request_exec(scp->channel, execbuffer);
|
||||||
|
+ if (rc == SSH_ERROR){
|
||||||
|
+ ssh_set_error(scp->session, SSH_FATAL,
|
||||||
|
+ "Failed executing command: %s", execbuffer);
|
||||||
|
scp->state = SSH_SCP_ERROR;
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
cgit v1.2.1
|
||||||
|
|
||||||
13
libssh.spec
13
libssh.spec
@ -1,6 +1,6 @@
|
|||||||
Name: libssh
|
Name: libssh
|
||||||
Version: 0.8.3
|
Version: 0.8.3
|
||||||
Release: 5
|
Release: 6
|
||||||
Summary: A library implementing the SSH protocol
|
Summary: A library implementing the SSH protocol
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://www.libssh.org
|
URL: https://www.libssh.org
|
||||||
@ -20,6 +20,11 @@ Patch6004: libssh-stable-0p8-CVE-2018-10933-part5.patch
|
|||||||
Patch6005: libssh-stable-0p8-CVE-2018-10933-part6.patch
|
Patch6005: libssh-stable-0p8-CVE-2018-10933-part6.patch
|
||||||
Patch6006: libssh-stable-0p8-CVE-2018-10933-part7.patch
|
Patch6006: libssh-stable-0p8-CVE-2018-10933-part7.patch
|
||||||
Patch6007: libssh-stable-0p8-CVE-2018-10933-part8.patch
|
Patch6007: libssh-stable-0p8-CVE-2018-10933-part8.patch
|
||||||
|
Patch6008: 0001-CVE-2019-14889.patch
|
||||||
|
Patch6009: 0002-CVE-2019-14889.patch
|
||||||
|
Patch6010: 0003-CVE-2019-14889.patch
|
||||||
|
Patch6011: 0004-CVE-2019-14889.patch
|
||||||
|
Patch6012: 0005-CVE-2019-14889.patch
|
||||||
|
|
||||||
BuildRequires: cmake libcmocka-devel krb5-devel zlib-devel pkgconfig
|
BuildRequires: cmake libcmocka-devel krb5-devel zlib-devel pkgconfig
|
||||||
BuildRequires: doxygen gcc-c++ gnupg2 openssl-devel
|
BuildRequires: doxygen gcc-c++ gnupg2 openssl-devel
|
||||||
@ -102,6 +107,12 @@ popd
|
|||||||
%doc README ChangeLog obj/doc/html
|
%doc README ChangeLog obj/doc/html
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sun Jan 12 2020 openEuler Buildteam <buildteam@openeuler.org> - 0.8.3-6
|
||||||
|
- Type:bugfix
|
||||||
|
- Id:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: fixes cves
|
||||||
|
|
||||||
* Sat Dec 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 0.8.3-5
|
* Sat Dec 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 0.8.3-5
|
||||||
- Type:bugfix
|
- Type:bugfix
|
||||||
- Id:NA
|
- Id:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user