summaryrefslogtreecommitdiff
path: root/sftp-client.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-12-07 10:31:08 +1100
committerDamien Miller <djm@mindrot.org>2013-12-07 10:31:08 +1100
commit393920745fd328d3fe07f739a3cf7e1e6db45b60 (patch)
tree75c73ad0f58ede2b906c185ce83305519c067eb7 /sftp-client.c
parent534b2ccadea5e5e9a8b27226e6faac3ed5552e97 (diff)
- 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
Diffstat (limited to 'sftp-client.c')
-rw-r--r--sftp-client.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/sftp-client.c b/sftp-client.c
index 246e94982..1eb821086 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-client.c,v 1.110 2013/12/04 04:20:01 djm Exp $ */ 1/* $OpenBSD: sftp-client.c,v 1.111 2013/12/05 22:59:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -460,6 +460,10 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
460 Buffer msg; 460 Buffer msg;
461 u_int count, type, id, handle_len, i, expected_id, ents = 0; 461 u_int count, type, id, handle_len, i, expected_id, ents = 0;
462 char *handle; 462 char *handle;
463 int status = SSH2_FX_FAILURE;
464
465 if (dir)
466 *dir = NULL;
463 467
464 id = conn->msg_id++; 468 id = conn->msg_id++;
465 469
@@ -506,20 +510,12 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
506 fatal("ID mismatch (%u != %u)", id, expected_id); 510 fatal("ID mismatch (%u != %u)", id, expected_id);
507 511
508 if (type == SSH2_FXP_STATUS) { 512 if (type == SSH2_FXP_STATUS) {
509 int status = buffer_get_int(&msg); 513 status = buffer_get_int(&msg);
510
511 debug3("Received SSH2_FXP_STATUS %d", status); 514 debug3("Received SSH2_FXP_STATUS %d", status);
512 515 if (status == SSH2_FX_EOF)
513 if (status == SSH2_FX_EOF) {
514 break; 516 break;
515 } else { 517 error("Couldn't read directory: %s", fx2txt(status));
516 error("Couldn't read directory: %s", 518 goto out;
517 fx2txt(status));
518 do_close(conn, handle, handle_len);
519 free(handle);
520 buffer_free(&msg);
521 return(status);
522 }
523 } else if (type != SSH2_FXP_NAME) 519 } else if (type != SSH2_FXP_NAME)
524 fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", 520 fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
525 SSH2_FXP_NAME, type); 521 SSH2_FXP_NAME, type);
@@ -547,10 +543,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
547 if (strchr(filename, '/') != NULL) { 543 if (strchr(filename, '/') != NULL) {
548 error("Server sent suspect path \"%s\" " 544 error("Server sent suspect path \"%s\" "
549 "during readdir of \"%s\"", filename, path); 545 "during readdir of \"%s\"", filename, path);
550 goto next; 546 } else if (dir) {
551 }
552
553 if (dir) {
554 *dir = xrealloc(*dir, ents + 2, sizeof(**dir)); 547 *dir = xrealloc(*dir, ents + 2, sizeof(**dir));
555 (*dir)[ents] = xcalloc(1, sizeof(***dir)); 548 (*dir)[ents] = xcalloc(1, sizeof(***dir));
556 (*dir)[ents]->filename = xstrdup(filename); 549 (*dir)[ents]->filename = xstrdup(filename);
@@ -558,24 +551,29 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag,
558 memcpy(&(*dir)[ents]->a, a, sizeof(*a)); 551 memcpy(&(*dir)[ents]->a, a, sizeof(*a));
559 (*dir)[++ents] = NULL; 552 (*dir)[++ents] = NULL;
560 } 553 }
561 next:
562 free(filename); 554 free(filename);
563 free(longname); 555 free(longname);
564 } 556 }
565 } 557 }
558 status = 0;
566 559
560 out:
567 buffer_free(&msg); 561 buffer_free(&msg);
568 do_close(conn, handle, handle_len); 562 do_close(conn, handle, handle_len);
569 free(handle); 563 free(handle);
570 564
571 /* Don't return partial matches on interrupt */ 565 if (status != 0 && dir != NULL) {
572 if (interrupted && dir != NULL && *dir != NULL) { 566 /* Don't return results on error */
567 free_sftp_dirents(*dir);
568 *dir = NULL;
569 } else if (interrupted && dir != NULL && *dir != NULL) {
570 /* Don't return partial matches on interrupt */
573 free_sftp_dirents(*dir); 571 free_sftp_dirents(*dir);
574 *dir = xcalloc(1, sizeof(**dir)); 572 *dir = xcalloc(1, sizeof(**dir));
575 **dir = NULL; 573 **dir = NULL;
576 } 574 }
577 575
578 return 0; 576 return status;
579} 577}
580 578
581int 579int
@@ -588,6 +586,8 @@ void free_sftp_dirents(SFTP_DIRENT **s)
588{ 586{
589 int i; 587 int i;
590 588
589 if (s == NULL)
590 return;
591 for (i = 0; s[i]; i++) { 591 for (i = 0; s[i]; i++) {
592 free(s[i]->filename); 592 free(s[i]->filename);
593 free(s[i]->longname); 593 free(s[i]->longname);