From 730fdef61ddad6e08cf1ab625fba9a0629009235 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sat, 31 Aug 2024 13:49:04 +0300 Subject: [PATCH] (tar_read_header): simplify read_header overflow checking. Use ckd_add instead of doing overflow checking by hand. Although the old code was correct on all practical hosts, the new code is simpler and works even on weird hosts where SIZE_MAX <= INT_MAX. Sync with GNU tar 8a3fc529729acf38276b27f6b7bc50962dfab799. Signed-off-by: Andrew Borodin --- src/vfs/tar/tar.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vfs/tar/tar.c b/src/vfs/tar/tar.c index d07597f4c..36cccacc9 100644 --- a/src/vfs/tar/tar.c +++ b/src/vfs/tar/tar.c @@ -36,6 +36,11 @@ #include #include +#ifdef HAVE_STDCKDINT_H +#include +#else +#include "lib/stdckdint.h" +#endif #include /* memset() */ #ifdef hpux @@ -636,8 +641,6 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive) if (header->header.typeflag == GNUTYPE_LONGNAME || header->header.typeflag == GNUTYPE_LONGLINK) { - size_t name_size = current_stat_info.stat.st_size; - size_t n; off_t size; union block *header_copy; char *bp; @@ -646,17 +649,15 @@ tar_read_header (struct vfs_class *me, struct vfs_s_super *archive) if (arch->type == TAR_UNKNOWN) arch->type = TAR_GNU; - n = name_size % BLOCKSIZE; - size = name_size + BLOCKSIZE; - if (n != 0) - size += BLOCKSIZE - n; - if ((off_t) name_size != current_stat_info.stat.st_size || size < (off_t) name_size) + if (ckd_add (&size, current_stat_info.stat.st_size, 2 * BLOCKSIZE - 1)) { message (D_ERROR, MSG_ERROR, _("Inconsistent tar archive")); status = HEADER_FAILURE; goto ret; } + size -= size % BLOCKSIZE; + header_copy = g_malloc (size + 1); if (header->header.typeflag == GNUTYPE_LONGNAME)