diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-08-04 18:15:19 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-08-04 18:15:19 +0200 |
commit | 037759bb4f57b0cb9b0daf6ffed43f90b62b8cb4 (patch) | |
tree | 64a7f3b7d8ca50d3e622c9f1a1bb2b91198723d9 | |
parent | 45d68c3749d29339494eb38bb4d5fe3ea189ac77 (diff) | |
download | busybox-w32-037759bb4f57b0cb9b0daf6ffed43f90b62b8cb4.tar.gz busybox-w32-037759bb4f57b0cb9b0daf6ffed43f90b62b8cb4.tar.bz2 busybox-w32-037759bb4f57b0cb9b0daf6ffed43f90b62b8cb4.zip |
tar: handle the case when opened created tarball happens to have fd#0
Reproducer:
exec 0>&-
exec 1>&-
tar czf z.tar.gz FILE
function old new delta
vfork_compressor 229 257 +28
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/tar.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/archival/tar.c b/archival/tar.c index 9239d8ee4..120c77f3b 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -611,6 +611,7 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) | |||
611 | 611 | ||
612 | if (xvfork() == 0) { | 612 | if (xvfork() == 0) { |
613 | /* child */ | 613 | /* child */ |
614 | int tfd; | ||
614 | /* NB: close _first_, then move fds! */ | 615 | /* NB: close _first_, then move fds! */ |
615 | close(data.wr); | 616 | close(data.wr); |
616 | # if WAIT_FOR_CHILD | 617 | # if WAIT_FOR_CHILD |
@@ -619,8 +620,23 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) | |||
619 | * parent waits for this close to happen */ | 620 | * parent waits for this close to happen */ |
620 | fcntl(status.wr, F_SETFD, FD_CLOEXEC); | 621 | fcntl(status.wr, F_SETFD, FD_CLOEXEC); |
621 | # endif | 622 | # endif |
623 | /* copy it: parent's tar_fd variable must not change */ | ||
624 | tfd = tar_fd; | ||
625 | if (tfd == 0) { | ||
626 | /* Output tar fd may be zero. | ||
627 | * xmove_fd(data.rd, 0) would destroy it. | ||
628 | * Reproducer: | ||
629 | * exec 0>&- | ||
630 | * exec 1>&- | ||
631 | * tar czf Z.tar.gz FILE | ||
632 | * Swapping move_fd's order wouldn't work: | ||
633 | * data.rd is 1 and _it_ would be destroyed. | ||
634 | */ | ||
635 | xmove_fd(tfd, 3); | ||
636 | tfd = 3; | ||
637 | } | ||
622 | xmove_fd(data.rd, 0); | 638 | xmove_fd(data.rd, 0); |
623 | xmove_fd(tar_fd, 1); | 639 | xmove_fd(tfd, 1); |
624 | /* exec gzip/bzip2 program/applet */ | 640 | /* exec gzip/bzip2 program/applet */ |
625 | BB_EXECLP(gzip, gzip, "-f", (char *)0); | 641 | BB_EXECLP(gzip, gzip, "-f", (char *)0); |
626 | vfork_exec_errno = errno; | 642 | vfork_exec_errno = errno; |
@@ -715,11 +731,7 @@ static NOINLINE int writeTarFile( | |||
715 | return errorFlag; | 731 | return errorFlag; |
716 | } | 732 | } |
717 | 733 | ||
718 | #else /* !FEATURE_TAR_CREATE */ | 734 | #endif /* FEATURE_TAR_CREATE */ |
719 | |||
720 | # define writeTarFile(...) 0 | ||
721 | |||
722 | #endif | ||
723 | 735 | ||
724 | #if ENABLE_FEATURE_TAR_FROM | 736 | #if ENABLE_FEATURE_TAR_FROM |
725 | static llist_t *append_file_list_to_list(llist_t *list) | 737 | static llist_t *append_file_list_to_list(llist_t *list) |