mirror of git://anongit.mindrot.org/openssh.git
- djm@cvs.openbsd.org 2013/12/05 22:59:45
[sftp-client.c] fix memory leak in error path in do_readdir(); pointed out by Loganaden Velvindron @ AfriNIC in bz#2163
This commit is contained in:
parent
534b2ccade
commit
393920745f
|
@ -1,3 +1,10 @@
|
||||||
|
20131207
|
||||||
|
- (djm) OpenBSD CVS Sync
|
||||||
|
- djm@cvs.openbsd.org 2013/12/05 22:59:45
|
||||||
|
[sftp-client.c]
|
||||||
|
fix memory leak in error path in do_readdir(); pointed out by
|
||||||
|
Loganaden Velvindron @ AfriNIC in bz#2163
|
||||||
|
|
||||||
20131205
|
20131205
|
||||||
- (djm) OpenBSD CVS Sync
|
- (djm) OpenBSD CVS Sync
|
||||||
- jmc@cvs.openbsd.org 2013/11/21 08:05:09
|
- jmc@cvs.openbsd.org 2013/11/21 08:05:09
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sftp-client.c,v 1.110 2013/12/04 04:20:01 djm Exp $ */
|
/* $OpenBSD: sftp-client.c,v 1.111 2013/12/05 22:59:45 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||||
*
|
*
|
||||||
|
@ -460,6 +460,10 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
|
||||||
Buffer msg;
|
Buffer msg;
|
||||||
u_int count, type, id, handle_len, i, expected_id, ents = 0;
|
u_int count, type, id, handle_len, i, expected_id, ents = 0;
|
||||||
char *handle;
|
char *handle;
|
||||||
|
int status = SSH2_FX_FAILURE;
|
||||||
|
|
||||||
|
if (dir)
|
||||||
|
*dir = NULL;
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
|
|
||||||
|
@ -506,20 +510,12 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
|
||||||
fatal("ID mismatch (%u != %u)", id, expected_id);
|
fatal("ID mismatch (%u != %u)", id, expected_id);
|
||||||
|
|
||||||
if (type == SSH2_FXP_STATUS) {
|
if (type == SSH2_FXP_STATUS) {
|
||||||
int status = buffer_get_int(&msg);
|
status = buffer_get_int(&msg);
|
||||||
|
|
||||||
debug3("Received SSH2_FXP_STATUS %d", status);
|
debug3("Received SSH2_FXP_STATUS %d", status);
|
||||||
|
if (status == SSH2_FX_EOF)
|
||||||
if (status == SSH2_FX_EOF) {
|
|
||||||
break;
|
break;
|
||||||
} else {
|
error("Couldn't read directory: %s", fx2txt(status));
|
||||||
error("Couldn't read directory: %s",
|
goto out;
|
||||||
fx2txt(status));
|
|
||||||
do_close(conn, handle, handle_len);
|
|
||||||
free(handle);
|
|
||||||
buffer_free(&msg);
|
|
||||||
return(status);
|
|
||||||
}
|
|
||||||
} else if (type != SSH2_FXP_NAME)
|
} else if (type != SSH2_FXP_NAME)
|
||||||
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
|
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
|
||||||
SSH2_FXP_NAME, type);
|
SSH2_FXP_NAME, type);
|
||||||
|
@ -547,10 +543,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
|
||||||
if (strchr(filename, '/') != NULL) {
|
if (strchr(filename, '/') != NULL) {
|
||||||
error("Server sent suspect path \"%s\" "
|
error("Server sent suspect path \"%s\" "
|
||||||
"during readdir of \"%s\"", filename, path);
|
"during readdir of \"%s\"", filename, path);
|
||||||
goto next;
|
} else if (dir) {
|
||||||
}
|
|
||||||
|
|
||||||
if (dir) {
|
|
||||||
*dir = xrealloc(*dir, ents + 2, sizeof(**dir));
|
*dir = xrealloc(*dir, ents + 2, sizeof(**dir));
|
||||||
(*dir)[ents] = xcalloc(1, sizeof(***dir));
|
(*dir)[ents] = xcalloc(1, sizeof(***dir));
|
||||||
(*dir)[ents]->filename = xstrdup(filename);
|
(*dir)[ents]->filename = xstrdup(filename);
|
||||||
|
@ -558,24 +551,29 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
|
||||||
memcpy(&(*dir)[ents]->a, a, sizeof(*a));
|
memcpy(&(*dir)[ents]->a, a, sizeof(*a));
|
||||||
(*dir)[++ents] = NULL;
|
(*dir)[++ents] = NULL;
|
||||||
}
|
}
|
||||||
next:
|
|
||||||
free(filename);
|
free(filename);
|
||||||
free(longname);
|
free(longname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
status = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
buffer_free(&msg);
|
buffer_free(&msg);
|
||||||
do_close(conn, handle, handle_len);
|
do_close(conn, handle, handle_len);
|
||||||
free(handle);
|
free(handle);
|
||||||
|
|
||||||
/* Don't return partial matches on interrupt */
|
if (status != 0 && dir != NULL) {
|
||||||
if (interrupted && dir != NULL && *dir != NULL) {
|
/* Don't return results on error */
|
||||||
|
free_sftp_dirents(*dir);
|
||||||
|
*dir = NULL;
|
||||||
|
} else if (interrupted && dir != NULL && *dir != NULL) {
|
||||||
|
/* Don't return partial matches on interrupt */
|
||||||
free_sftp_dirents(*dir);
|
free_sftp_dirents(*dir);
|
||||||
*dir = xcalloc(1, sizeof(**dir));
|
*dir = xcalloc(1, sizeof(**dir));
|
||||||
**dir = NULL;
|
**dir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -588,6 +586,8 @@ void free_sftp_dirents(SFTP_DIRENT **s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
return;
|
||||||
for (i = 0; s[i]; i++) {
|
for (i = 0; s[i]; i++) {
|
||||||
free(s[i]->filename);
|
free(s[i]->filename);
|
||||||
free(s[i]->longname);
|
free(s[i]->longname);
|
||||||
|
|
Loading…
Reference in New Issue