Fix smbclient/tarmode panic on connecting to Windows 2000 clients.
authorSalvador I. Gonzalez <sgonzalez@codejunkie.net>
Sat, 11 Aug 2012 17:46:41 +0000 (13:46 -0400)
committerJeremy Allison <jra@samba.org>
Mon, 13 Aug 2012 21:12:50 +0000 (23:12 +0200)
  'Freed frame ../source3/libsmb/clilist.c:934, expected ../source3/client/clitar.c:821'
  Cause: (strequal(finfo->name,"..") || strequal(finfo->name,"."))
    evaluates to true, do_tar returns without freeing ctx

Signed-off-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Mon Aug 13 23:12:50 CEST 2012 on sn-devel-104

source3/client/clitar.c

index cae512b5e9bfe7a2aecfc05da39a956e86a5cd75..d3525719f5e2449688302ceba10a631ff4950895 100644 (file)
@@ -821,8 +821,10 @@ static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
        TALLOC_CTX *ctx = talloc_stackframe();
        NTSTATUS status = NT_STATUS_OK;
 
-       if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
-               return NT_STATUS_OK;
+       if (strequal(finfo->name,"..") || strequal(finfo->name,".")) {
+               status = NT_STATUS_OK;
+               goto cleanup;
+       }
 
        /* Is it on the exclude list ? */
        if (!tar_excl && clipn) {
@@ -835,7 +837,8 @@ static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
                                client_get_cur_dir(),
                                finfo->name);
                if (!exclaim) {
-                       return NT_STATUS_NO_MEMORY;
+                       status = NT_STATUS_NO_MEMORY;
+                       goto cleanup;
                }
 
                DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
@@ -844,7 +847,8 @@ static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
                                (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) {
                        DEBUG(3,("Skipping file %s\n", exclaim));
                        TALLOC_FREE(exclaim);
-                       return NT_STATUS_OK;
+                       status = NT_STATUS_OK;
+                       goto cleanup;
                }
                TALLOC_FREE(exclaim);
        }
@@ -856,7 +860,8 @@ static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
 
                saved_curdir = talloc_strdup(ctx, client_get_cur_dir());
                if (!saved_curdir) {
-                       return NT_STATUS_NO_MEMORY;
+                       status = NT_STATUS_NO_MEMORY;
+                       goto cleanup;
                }
 
                DEBUG(5, ("strlen(cur_dir)=%d, \
@@ -869,7 +874,8 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
                                client_get_cur_dir(),
                                finfo->name);
                if (!new_cd) {
-                       return NT_STATUS_NO_MEMORY;
+                       status = NT_STATUS_NO_MEMORY;
+                       goto cleanup;
                }
                client_set_cur_dir(new_cd);
 
@@ -888,7 +894,8 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
                                "%s*",
                                client_get_cur_dir());
                if (!mtar_mask) {
-                       return NT_STATUS_NO_MEMORY;
+                       status = NT_STATUS_NO_MEMORY;
+                       goto cleanup;
                }
                DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
                do_list(mtar_mask, attribute, do_tar, False, True);
@@ -902,11 +909,15 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
                                        client_get_cur_dir(),
                                        finfo->name);
                if (!rname) {
-                       return NT_STATUS_NO_MEMORY;
+                       status = NT_STATUS_NO_MEMORY;
+                       goto cleanup;
                }
                status = do_atar(rname,finfo->name,finfo);
                TALLOC_FREE(rname);
        }
+
+  cleanup:
+       TALLOC_FREE(ctx);
        return status;
 }