1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-30 13:01:23 +03:00

misc: Avoid the 4KB stack buffer in ssh_path_expand_escape

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Change-Id: I908ef4dfa960bf89f8e42f99af2f8bcdbb006bc8
This commit is contained in:
Xiang Xiao
2021-05-10 01:13:09 +08:00
committed by Jakub Jelen
parent f2bd44969b
commit 9eba361ca2

View File

@@ -1105,8 +1105,9 @@ char *ssh_path_expand_tilde(const char *d) {
*/ */
char *ssh_path_expand_escape(ssh_session session, const char *s) { char *ssh_path_expand_escape(ssh_session session, const char *s) {
char host[NI_MAXHOST]; char host[NI_MAXHOST];
char buf[MAX_BUF_SIZE]; char *buf = NULL;
char *r, *x = NULL; char *r = NULL;
char *x = NULL;
const char *p; const char *p;
size_t i, l; size_t i, l;
@@ -1122,6 +1123,13 @@ char *ssh_path_expand_escape(ssh_session session, const char *s) {
return NULL; return NULL;
} }
buf = malloc(MAX_BUF_SIZE);
if (buf == NULL) {
ssh_set_error_oom(session);
free(r);
return NULL;
}
p = r; p = r;
buf[0] = '\0'; buf[0] = '\0';
@@ -1131,6 +1139,7 @@ char *ssh_path_expand_escape(ssh_session session, const char *s) {
buf[i] = *p; buf[i] = *p;
i++; i++;
if (i >= MAX_BUF_SIZE) { if (i >= MAX_BUF_SIZE) {
free(buf);
free(r); free(r);
return NULL; return NULL;
} }
@@ -1177,12 +1186,14 @@ char *ssh_path_expand_escape(ssh_session session, const char *s) {
default: default:
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Wrong escape sequence detected"); "Wrong escape sequence detected");
free(buf);
free(r); free(r);
return NULL; return NULL;
} }
if (x == NULL) { if (x == NULL) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
free(buf);
free(r); free(r);
return NULL; return NULL;
} }
@@ -1191,19 +1202,26 @@ char *ssh_path_expand_escape(ssh_session session, const char *s) {
if (i >= MAX_BUF_SIZE) { if (i >= MAX_BUF_SIZE) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"String too long"); "String too long");
free(buf);
free(x); free(x);
free(r); free(r);
return NULL; return NULL;
} }
l = strlen(buf); l = strlen(buf);
strncpy(buf + l, x, sizeof(buf) - l - 1); strncpy(buf + l, x, MAX_BUF_SIZE - l - 1);
buf[i] = '\0'; buf[i] = '\0';
SAFE_FREE(x); SAFE_FREE(x);
} }
free(r); free(r);
return strdup(buf);
#undef MAX_BUF_SIZE /* strip the unused space by realloc */
x = realloc(buf, strlen(buf) + 1);
if (x == NULL) {
ssh_set_error_oom(session);
free(buf);
}
return x;
} }
/** /**