- 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:
Damien Miller 2013-12-07 10:31:08 +11:00
parent 534b2ccade
commit 393920745f
2 changed files with 28 additions and 21 deletions

View File

@ -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

View File

@ -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);