Subversion Repositories

?revision_form?Rev ?revision_input??revision_submit??revision_endform?

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 magnus 1
Description: Fix memory leaks related to th_get_pathname()
2
Author: James Morrison <phython@debian.org>
3
Author: Martin Gadbois <martin.gadbois@colubris.com>
4
Author: Magnus Holmgren <holmgren@debian.org>
5
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libtar/+bug/41804
6
 
7
--- a/lib/wrapper.c
8
+++ b/lib/wrapper.c
9
@@ -18,6 +18,7 @@
10
 #include <errno.h>
11
 
12
 #ifdef STDC_HEADERS
13
+# include <stdlib.h>
14
 # include <string.h>
15
 #endif
16
 
17
@@ -35,7 +36,10 @@ tar_extract_glob(TAR *t, char *globname,
18
                if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
19
                {
20
                        if (TH_ISREG(t) && tar_skip_regfile(t))
21
+                       {
22
+                               free(filename);
23
                                return -1;
24
+                       }
25
                        continue;
26
                }
27
                if (t->options & TAR_VERBOSE)
28
@@ -45,7 +49,11 @@ tar_extract_glob(TAR *t, char *globname,
29
                else
30
                        strlcpy(buf, filename, sizeof(buf));
31
                if (tar_extract_file(t, filename) != 0)
32
+               {
33
+                       free(filename);
34
                        return -1;
35
+               }
36
+               free(filename);
37
        }
38
 
39
        return (i == 1 ? 0 : -1);
40
@@ -76,12 +84,17 @@ tar_extract_all(TAR *t, char *prefix)
41
                        snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
42
                else
43
                        strlcpy(buf, filename, sizeof(buf));
44
+               free(filename);
45
 #ifdef DEBUG
46
                printf("    tar_extract_all(): calling tar_extract_file(t, "
47
                       "\"%s\")\n", buf);
48
 #endif
49
                if (tar_extract_file(t, buf) != 0)
50
+               {
51
+                       free(filename);
52
                        return -1;
53
+               }
54
+               free(filename);
55
        }
56
 
57
        return (i == 1 ? 0 : -1);
58
--- a/lib/extract.c
59
+++ b/lib/extract.c
60
@@ -21,6 +21,7 @@
61
 
62
 #ifdef STDC_HEADERS
63
 # include <stdlib.h>
64
+# include <string.h>
65
 #endif
66
 
67
 #ifdef HAVE_UNISTD_H
68
@@ -43,9 +44,10 @@ tar_set_file_perms(TAR *t, char *realnam
69
        uid_t uid;
70
        gid_t gid;
71
        struct utimbuf ut;
72
-       char *filename;
73
+       char *filename,*pathname;
74
 
75
-       filename = (realname ? realname : th_get_pathname(t));
76
+       pathname = th_get_pathname(t);
77
+       filename = (realname ? realname : pathname);
78
        mode = th_get_mode(t);
79
        uid = th_get_uid(t);
80
        gid = th_get_gid(t);
81
@@ -68,6 +70,7 @@ tar_set_file_perms(TAR *t, char *realnam
82
                                filename, uid, gid, strerror(errno));
83
 # endif
84
 #endif /* HAVE_LCHOWN */
85
+                       free(pathname);
86
                        return -1;
87
                }
88
 
89
@@ -77,6 +80,7 @@ tar_set_file_perms(TAR *t, char *realnam
90
 #ifdef DEBUG
91
                perror("utime()");
92
 #endif
93
+               free(pathname);
94
                return -1;
95
        }
96
 
97
@@ -86,9 +90,10 @@ tar_set_file_perms(TAR *t, char *realnam
98
 #ifdef DEBUG
99
                perror("chmod()");
100
 #endif
101
+               free(pathname);
102
                return -1;
103
        }
104
-
105
+       free(pathname);
106
        return 0;
107
 }
108
 
109
@@ -99,6 +104,7 @@ tar_extract_file(TAR *t, char *realname)
110
 {
111
        int i;
112
        linkname_t *lnp;
113
+       char *pathname;
114
 
115
        if (t->options & TAR_NOOVERWRITE)
116
        {
117
@@ -140,12 +146,14 @@ tar_extract_file(TAR *t, char *realname)
118
        lnp = (linkname_t *)calloc(1, sizeof(linkname_t));
119
        if (lnp == NULL)
120
                return -1;
121
-       strlcpy(lnp->ln_save, th_get_pathname(t), sizeof(lnp->ln_save));
122
+       pathname = th_get_pathname(t);
123
+       strlcpy(lnp->ln_save, pathname, sizeof(lnp->ln_save));
124
        strlcpy(lnp->ln_real, realname, sizeof(lnp->ln_real));
125
 #ifdef DEBUG
126
        printf("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", "
127
-              "value=\"%s\"\n", th_get_pathname(t), realname);
128
+              "value=\"%s\"\n", pathname, realname);
129
 #endif
130
+       free(pathname);
131
        if (libtar_hash_add(t->h, lnp) != 0)
132
                return -1;
133
 
134
@@ -164,7 +172,7 @@ tar_extract_regfile(TAR *t, char *realna
135
        int fdout;
136
        int i, k;
137
        char buf[T_BLOCKSIZE];
138
-       char *filename;
139
+       char *filename,*pathname;
140
 
141
 #ifdef DEBUG
142
        printf("==> tar_extract_regfile(t=0x%lx, realname=\"%s\")\n", t,
143
@@ -176,15 +184,18 @@ tar_extract_regfile(TAR *t, char *realna
144
                errno = EINVAL;
145
                return -1;
146
        }
147
-
148
-       filename = (realname ? realname : th_get_pathname(t));
149
+       pathname = th_get_pathname(t);
150
+       filename = (realname ? realname : pathname);
151
        mode = th_get_mode(t);
152
        size = th_get_size(t);
153
        uid = th_get_uid(t);
154
        gid = th_get_gid(t);
155
 
156
        if (mkdirhier(dirname(filename)) == -1)
157
+       {
158
+               free(pathname);
159
                return -1;
160
+       }
161
 
162
 #ifdef DEBUG
163
        printf("  ==> extracting: %s (mode %04o, uid %d, gid %d, %d bytes)\n",
164
@@ -200,6 +211,7 @@ tar_extract_regfile(TAR *t, char *realna
165
 #ifdef DEBUG
166
                perror("open()");
167
 #endif
168
+               free(pathname);
169
                return -1;
170
        }
171
 
172
@@ -231,23 +243,30 @@ tar_extract_regfile(TAR *t, char *realna
173
                {
174
                        if (k != -1)
175
                                errno = EINVAL;
176
+                       free(pathname);
177
                        return -1;
178
                }
179
 
180
                /* write block to output file */
181
                if (write(fdout, buf,
182
                          ((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i)) == -1)
183
+               {
184
+                       free(pathname);
185
                        return -1;
186
+               }
187
        }
188
 
189
        /* close output file */
190
        if (close(fdout) == -1)
191
+       {
192
+               free(pathname);
193
                return -1;
194
+       }
195
 
196
 #ifdef DEBUG
197
        printf("### done extracting %s\n", filename);
198
 #endif
199
-
200
+       free(pathname);
201
        return 0;
202
 }
203
 
204
@@ -286,7 +305,7 @@ tar_skip_regfile(TAR *t)
205
 int
206
 tar_extract_hardlink(TAR * t, char *realname)
207
 {
208
-       char *filename;
209
+       char *filename,*pathname;
210
        char *linktgt = NULL;
211
        linkname_t *lnp;
212
        libtar_hashptr_t hp;
213
@@ -296,10 +315,14 @@ tar_extract_hardlink(TAR * t, char *real
214
                errno = EINVAL;
215
                return -1;
216
        }
217
-
218
-       filename = (realname ? realname : th_get_pathname(t));
219
+       
220
+       pathname = th_get_pathname(t);
221
+       filename = (realname ? realname : pathname);
222
        if (mkdirhier(dirname(filename)) == -1)
223
+       {
224
+               free(pathname);
225
                return -1;
226
+       }
227
        libtar_hashptr_reset(&hp);
228
        if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
229
                               (libtar_matchfunc_t)libtar_str_match) != 0)
230
@@ -318,9 +341,10 @@ tar_extract_hardlink(TAR * t, char *real
231
 #ifdef DEBUG
232
                perror("link()");
233
 #endif
234
+               free(pathname);
235
                return -1;
236
        }
237
-
238
+       free(pathname);
239
        return 0;
240
 }
241
 
242
@@ -329,7 +353,7 @@ tar_extract_hardlink(TAR * t, char *real
243
 int
244
 tar_extract_symlink(TAR *t, char *realname)
245
 {
246
-       char *filename;
247
+       char *filename,*pathname;
248
 
249
        if (!TH_ISSYM(t))
250
        {
251
@@ -337,12 +361,19 @@ tar_extract_symlink(TAR *t, char *realna
252
                return -1;
253
        }
254
 
255
-       filename = (realname ? realname : th_get_pathname(t));
256
+       pathname = th_get_pathname(t);
257
+       filename = (realname ? realname : pathname);
258
        if (mkdirhier(dirname(filename)) == -1)
259
+       {
260
+               free(pathname);
261
                return -1;
262
+       }
263
 
264
        if (unlink(filename) == -1 && errno != ENOENT)
265
+       {
266
+               free(pathname);
267
                return -1;
268
+       }
269
 
270
 #ifdef DEBUG
271
        printf("  ==> extracting: %s (symlink to %s)\n",
272
@@ -353,9 +384,10 @@ tar_extract_symlink(TAR *t, char *realna
273
 #ifdef DEBUG
274
                perror("symlink()");
275
 #endif
276
+               free(pathname);
277
                return -1;
278
        }
279
-
280
+       free(pathname);
281
        return 0;
282
 }
283
 
284
@@ -366,7 +398,7 @@ tar_extract_chardev(TAR *t, char *realna
285
 {
286
        mode_t mode;
287
        unsigned long devmaj, devmin;
288
-       char *filename;
289
+       char *filename,*pathname;
290
 
291
        if (!TH_ISCHR(t))
292
        {
293
@@ -374,13 +406,17 @@ tar_extract_chardev(TAR *t, char *realna
294
                return -1;
295
        }
296
 
297
-       filename = (realname ? realname : th_get_pathname(t));
298
+       pathname = th_get_pathname(t);
299
+       filename = (realname ? realname : pathname);
300
        mode = th_get_mode(t);
301
        devmaj = th_get_devmajor(t);
302
        devmin = th_get_devminor(t);
303
 
304
        if (mkdirhier(dirname(filename)) == -1)
305
+       {
306
+               free(pathname);
307
                return -1;
308
+       }
309
 
310
 #ifdef DEBUG
311
        printf("  ==> extracting: %s (character device %ld,%ld)\n",
312
@@ -392,9 +428,10 @@ tar_extract_chardev(TAR *t, char *realna
313
 #ifdef DEBUG
314
                perror("mknod()");
315
 #endif
316
+               free(pathname);
317
                return -1;
318
        }
319
-
320
+       free(pathname);
321
        return 0;
322
 }
323
 
324
@@ -405,7 +442,7 @@ tar_extract_blockdev(TAR *t, char *realn
325
 {
326
        mode_t mode;
327
        unsigned long devmaj, devmin;
328
-       char *filename;
329
+       char *filename,*pathname;
330
 
331
        if (!TH_ISBLK(t))
332
        {
333
@@ -413,13 +450,17 @@ tar_extract_blockdev(TAR *t, char *realn
334
                return -1;
335
        }
336
 
337
-       filename = (realname ? realname : th_get_pathname(t));
338
+       pathname = th_get_pathname(t);
339
+       filename = (realname ? realname : pathname);
340
        mode = th_get_mode(t);
341
        devmaj = th_get_devmajor(t);
342
        devmin = th_get_devminor(t);
343
 
344
        if (mkdirhier(dirname(filename)) == -1)
345
+       {
346
+               free(pathname);
347
                return -1;
348
+       }
349
 
350
 #ifdef DEBUG
351
        printf("  ==> extracting: %s (block device %ld,%ld)\n",
352
@@ -431,9 +472,10 @@ tar_extract_blockdev(TAR *t, char *realn
353
 #ifdef DEBUG
354
                perror("mknod()");
355
 #endif
356
+               free(pathname);
357
                return -1;
358
        }
359
-
360
+       free(pathname);
361
        return 0;
362
 }
363
 
364
@@ -443,7 +485,7 @@ int
365
 tar_extract_dir(TAR *t, char *realname)
366
 {
367
        mode_t mode;
368
-       char *filename;
369
+       char *filename,*pathname;
370
 
371
        if (!TH_ISDIR(t))
372
        {
373
@@ -451,11 +493,15 @@ tar_extract_dir(TAR *t, char *realname)
374
                return -1;
375
        }
376
 
377
-       filename = (realname ? realname : th_get_pathname(t));
378
+       pathname = th_get_pathname(t);
379
+       filename = (realname ? realname : pathname);
380
        mode = th_get_mode(t);
381
 
382
        if (mkdirhier(dirname(filename)) == -1)
383
+       {
384
+               free(pathname);
385
                return -1;
386
+       }
387
 
388
 #ifdef DEBUG
389
        printf("  ==> extracting: %s (mode %04o, directory)\n", filename,
390
@@ -470,6 +516,7 @@ tar_extract_dir(TAR *t, char *realname)
391
 #ifdef DEBUG
392
                                perror("chmod()");
393
 #endif
394
+                               free(pathname);
395
                                return -1;
396
                        }
397
                        else
398
@@ -477,6 +524,7 @@ tar_extract_dir(TAR *t, char *realname)
399
 #ifdef DEBUG
400
                                puts("  *** using existing directory");
401
 #endif
402
+                               free(pathname);
403
                                return 1;
404
                        }
405
                }
406
@@ -485,10 +533,11 @@ tar_extract_dir(TAR *t, char *realname)
407
 #ifdef DEBUG
408
                        perror("mkdir()");
409
 #endif
410
+                       free(pathname);
411
                        return -1;
412
                }
413
        }
414
-
415
+       free(pathname);
416
        return 0;
417
 }
418
 
419
@@ -498,7 +547,7 @@ int
420
 tar_extract_fifo(TAR *t, char *realname)
421
 {
422
        mode_t mode;
423
-       char *filename;
424
+       char *filename,*pathname;
425
 
426
        if (!TH_ISFIFO(t))
427
        {
428
@@ -506,11 +555,15 @@ tar_extract_fifo(TAR *t, char *realname)
429
                return -1;
430
        }
431
 
432
-       filename = (realname ? realname : th_get_pathname(t));
433
+       pathname = th_get_pathname(t);
434
+       filename = (realname ? realname : pathname);
435
        mode = th_get_mode(t);
436
 
437
        if (mkdirhier(dirname(filename)) == -1)
438
+       {
439
+               free(pathname);
440
                return -1;
441
+       }
442
 
443
 #ifdef DEBUG
444
        printf("  ==> extracting: %s (fifo)\n", filename);
445
@@ -520,9 +573,11 @@ tar_extract_fifo(TAR *t, char *realname)
446
 #ifdef DEBUG
447
                perror("mkfifo()");
448
 #endif
449
+               free(pathname);
450
                return -1;
451
        }
452
 
453
+       free(pathname);
454
        return 0;
455
 }
456
 
457
--- a/lib/output.c
458
+++ b/lib/output.c
459
@@ -20,6 +20,7 @@
460
 #include <sys/param.h>
461
 
462
 #ifdef STDC_HEADERS
463
+# include <stdlib.h>
464
 # include <string.h>
465
 #endif
466
 
467
@@ -71,6 +72,7 @@ th_print_long_ls(TAR *t)
468
        char groupname[_POSIX_LOGIN_NAME_MAX];
469
        time_t mtime;
470
        struct tm *mtm;
471
+       char *pathname;
472
 
473
 #ifdef HAVE_STRFTIME
474
        char timebuf[18];
475
@@ -114,7 +116,9 @@ th_print_long_ls(TAR *t)
476
               mtm->tm_mday, mtm->tm_hour, mtm->tm_min, mtm->tm_year + 1900);
477
 #endif
478
 
479
-       printf(" %s", th_get_pathname(t));
480
+       pathname = th_get_pathname(t);
481
+       printf(" %s", pathname);
482
+       free(pathname);
483
 
484
        if (TH_ISSYM(t) || TH_ISLNK(t))
485
        {
486
--- a/lib/decode.c
487
+++ b/lib/decode.c
488
@@ -29,7 +29,7 @@ th_get_pathname(TAR *t)
489
        char filename[MAXPATHLEN];
490
 
491
        if (t->th_buf.gnu_longname)
492
-               return t->th_buf.gnu_longname;
493
+               return strdup(t->th_buf.gnu_longname);
494
 
495
        if (t->th_buf.prefix[0] != '\0')
496
        {