Subject: bug#13588: Pax hangs in case big UID

From: Stefano Lattarini <[email-masked]>
Date: Sun, 28 Apr 2013 11:07:09 +0200

On 04/27/2013 06:21 PM, Pavel Raiskup wrote:
> Stefano, this patch is quite hard to follow because of the new
> indentation.
>
Sorry, I now attach a version formatted with the '-w', which should
be free from the noise caused by the indentation change.

>  But both checks are saying PASS for me now.
> 
> I have found one possible problem (missing one line):
> 
>> -    done
>> -    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
>> -    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
>> -    am__untar="$_am_tar -xf -"
> 
>> +      done
>> +      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
>> +      am__untar="$_am_tar -xf -"
> 
> Don't know whether the check now works correctly.
>
Oops, I messed up again :-(  Nice catch BTW.  I have re-introduced the
line removed by mistake.

The updated patch is attached (formatted both with and without the '-w'
option).

Thanks, and sorry for the confusion,
  Stefano
>From edfd3bc4c1057be0b5553b5789a44f1b77bb2b45 Mon Sep 17 00:00:00 2001
Message-Id: <edfd3bc4c[email-masked]>
From: Stefano Lattarini <[email-masked]>
Date: Sun, 17 Feb 2013 16:42:46 +0100
Subject: [PATCH] tar: format 'ustar' cannot support UID/GID longer than 21
 bits

See automake bug#8343 and bug#13588.

POSIX 1988 'ustar' format is defined with *fixed-size* fields. There
is notably a 21 bits limit (2097151) for the UID and the GID.

Tom Rini [email-masked] says (in bug#8343):

    When the user has a UID or GID that is larger than the ustar format
    supports, pax does not error out gracefully in some cases (FC13).

Marc Herbert <[email-masked]> adds (in bug#8343):

    When "configure" is run by a user with an UID bigger than 21 bits,
    BSD pax 3.4 aborts when trying to create the 'conftest.tar' test
    archive and leaves an empty or corrupted conftest.tar file behind.
    In the next step, pax tries to extract this incomplete or corrupted
    archive and this *** hangs the whole ./configure script ***.

    Note: GNU cpio 2.9 pretends to pass the test but it is a LIE: it
    silently truncates any big UID to its lower 21 bits. I don't know
    what can be the consequences of this lie.

    I think there is currently a design issue in automake/m4/tar.m4
    considering that a ustar archive should should *never* succeed when
    ./configure is run from a big user ID.

Months later, Petr Hracek <[email-masked]> reports a similar issue
(in bug#13588) for Fedora 17:

    I am trying to solve problem in case a user is created with big
    UID and during configuration pax hangs with message

        ATTENTION! pax archive volume change required.
        Ready for archive volume: 1
        Input archive name or "." to quit pax.
        Archive name >

    and needs user interaction.

    Reference: <https://bugzilla.redhat.com/show_bug.cgi?id=843376>

Time to fix this issue, on the line of a preliminary patch provided by
Petr Hracek in bug#13588.  The final patch ended up being remarkably
different from that original proposition, though.

* m4/tar.m4 (_AM_PROG_TAR): If the UID or GID of the current user is
too high (> 2097151), the 'ustar' format cannot work.  Adjust checks
accordingly.  Some related code reordering and clean-up.
* t/tar-ustar-id-too-high.sh: New test.
* t/list-of-tests.mk: Add it.
* t/tar.sh: While at it, tweak and enhance a little.
* t/tar2.sh: Likewise.
* t/tar3.sh: Likewise.
* t/tar-override.sh: Likewise.
* NEWS: Update.
* THANKS: Likewise.

Helped-by: Pavel Raiskup <[email-masked]>
Helped-by: Petr Hracek <[email-masked]>
Helped-by: Marc Herbert <[email-masked]>
Helped-by: Tom Rini <[email-masked]>
Signed-off-by: Stefano Lattarini <[email-masked]>
---
 NEWS                       |  6 ++++
 THANKS                     |  3 ++
 m4/tar.m4                  | 58 ++++++++++++++++++++++++------
 t/list-of-tests.mk         |  1 +
 t/tar-override.sh          | 17 +++++----
 t/tar-ustar-id-too-high.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++
 t/tar.sh                   | 11 +++---
 t/tar2.sh                  | 11 +++---
 t/tar3.sh                  | 10 +++---
 9 files changed, 175 insertions(+), 30 deletions(-)
 create mode 100755 t/tar-ustar-id-too-high.sh

diff --git a/NEWS b/NEWS
index f9a1fb1..863ffdf 100644
--- a/NEWS
+++ b/NEWS
@@ -78,6 +78,12 @@ New in 1.13.2:
 
 * Bugs fixed:
 
+  - When the 'ustar' option is used, the generated configure script no
+    longer risks hanging during the tests for the availability of the
+    'pax' utility, even if the user running configure has a UID or GID
+    that requires more than 21 bits to be represented.
+    See automake bug#8343 and bug#13588.
+
   - The obsolete macros AM_CONFIG_HEADER or AM_PROG_CC_STDC work once
     again, as they did in Automake 1.12.x (albeit printing runtime
     warnings in the 'obsolete' category).  Removing them has turned
diff --git a/THANKS b/THANKS
index 66498d4..a574909 100644
--- a/THANKS
+++ b/THANKS
@@ -224,6 +224,7 @@ Luo Yi                          [email-masked]
 Maciej Stachowiak               [email-masked]
 Maciej W. Rozycki               [email-masked]
 Manu Rouat                      [email-masked]
+Marc Herbert                    [email-masked]
 Marcus Brinkmann                [email-masked]
 Marcus G. Daniels               [email-masked]
 Marius Vollmer                  [email-masked]
@@ -311,6 +312,7 @@ Peter Muir                      [email-masked]
 Peter O'Gorman                  [email-masked]
 Peter Rosin                     [email-masked]
 Peter Seiderer                  [email-masked]
+Petr Hracek                     [email-masked]
 Petter Reinholdtsen             [email-masked]
 Petteri Räty                    [email-masked]
 Phil Edwards                    [email-masked]
@@ -391,6 +393,7 @@ Tim Rice                        [email-masked]
 Tim Van Holder                  [email-masked]
 Toshio Kuratomi                 [email-masked]
 Tom Epperly                     [email-masked]
+Tom Rini                        [email-masked]
 Ulrich Drepper                  [email-masked]
 Ulrich Eckhardt                 [email-masked]
 Václav Haisman                  [email-masked]
diff --git a/m4/tar.m4 b/m4/tar.m4
index ec8c83e..aac6d8f 100644
--- a/m4/tar.m4
+++ b/m4/tar.m4
@@ -19,26 +19,62 @@
 # Substitute a variable $(am__untar) that extract such
 # a tarball read from stdin.
 #     $(am__untar) < result.tar
+#
 AC_DEFUN([_AM_PROG_TAR],
 [# Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
 m4_if([$1], [v7],
   [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
-     [m4_case([$1], [ustar],, [pax],,
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
   [m4_fatal([Unknown tar format])])
+
   AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
   _am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of '-'.
-for _am_tool in $_am_tools
-do
+
+  for _am_tool in $_am_tools; do
     case $_am_tool in
     gnutar)
-    for _am_tar in tar gnutar gtar;
-    do
+      for _am_tar in tar gnutar gtar; do
         AM_RUN_LOG([$_am_tar --version]) && break
       done
       am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
@@ -74,7 +110,7 @@ do
     # and am__untar set.
     test -n "${am_cv_prog_tar_$1}" && break
 
-  # tar/untar a dummy directory, and stop if the command works
+    # tar/untar a dummy directory, and stop if the command works.
     rm -rf conftest.dir
     mkdir conftest.dir
     echo GrepMe > conftest.dir/file
@@ -82,6 +118,7 @@ do
     rm -rf conftest.dir
     if test -s conftest.tar; then
       AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
       grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
     fi
   done
@@ -89,6 +126,7 @@ rm -rf conftest.dir
 
   AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
   AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+  
 AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index f1e3dca..664a902 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -1151,6 +1151,7 @@ t/tags-pr12372.sh \
 t/tar.sh \
 t/tar2.sh \
 t/tar3.sh \
+t/tar-ustar-id-too-high.sh \
 t/tar-override.sh \
 t/target-cflags.sh \
 t/targetclash.sh \
diff --git a/t/tar-override.sh b/t/tar-override.sh
index 863b9ab..bbf3fbb 100755
--- a/t/tar-override.sh
+++ b/t/tar-override.sh
@@ -16,8 +16,8 @@
 
 # Check that the user can override the tar program used by "make dist"
 # at runtime, by redefining the 'TAR' environment variable.
-# FIXME: currently this works only when the tar format used is 'v7'
-# FIXME: (which is the default one).
+# NOTE: currently this works only when the tar format used is 'v7'
+#       (which is the default one).
 
 . test-init.sh
 
@@ -35,6 +35,7 @@ chmod a+x am--tar
 
 cat > Makefile.am <<'END'
 check-local: dist
+	ls -l ;: For debugging.
 	test -f am--tar-has-run
 CLEANFILES = am--tar-has-run
 END
@@ -44,22 +45,24 @@ $AUTOCONF
 $AUTOMAKE
 ./configure
 
+clean_temp () { rm -f *.tar.* *has-run*; }
+
 $MAKE dist
-test -f $me-1.0.tar.gz
+test -f $distdir.tar.gz
 ls | grep has-run && exit 1
 
-rm -f *.tar.* *has-run*
+clean_temp
 
 TAR="$cwd/am--tar foo" $MAKE distcheck
-test -f $me-1.0.tar.gz
+test -f $distdir.tar.gz
 test "$(cat am--tar-has-run)" = foo
 
-rm -f *.tar.* *has-run*
+clean_temp
 
 TAR=; unset TAR
 # Creative use of eval to pacify maintainer checks.
 eval \$'MAKE dist "TAR=./am--tar mu"'
-test -f $me-1.0.tar.gz
+test -f $distdir.tar.gz
 test "$(cat am--tar-has-run)" = mu
 
 :
diff --git a/t/tar-ustar-id-too-high.sh b/t/tar-ustar-id-too-high.sh
new file mode 100755
index 0000000..79ae89d
--- /dev/null
+++ b/t/tar-ustar-id-too-high.sh
@@ -0,0 +1,88 @@
+#! /bin/sh
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Check that UID or GID too high for the ustar format are correctly
+# rwcognized and diagnosed by configure.  See bug#8343 and bug#13588.
+
+. test-init.sh
+
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
+AM_INIT_AUTOMAKE([tar-ustar])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+END
+
+: > Makefile.am
+
+run_configure()
+{
+  st=0; ./configure ${1+"$@"}  >stdout || st=$?
+  cat stdout || exit 1
+  test $st -eq 0 || exit 1
+}
+
+checked ()
+{
+  grep "^checking $1\.\.\. $2$" stdout
+}
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+mkdir bin
+cat > bin/id <<'END'
+#!/bin/sh -e
+case "$*" in
+  -u) echo "${am_uid-1000}";;
+  -g) echo "${am_gid-1000}";;
+   *) echo "id: bad/unexpected usage" >&2; exit 1;;
+esac
+END
+chmod a+x bin/id
+
+PATH=$(pwd)/bin$PATH_SEPARATOR$PATH
+
+# Problematic ID reported in
+# <https://bugzilla.redhat.com/show_bug.cgi?id=843376>.
+am_uid=16777216; export am_uid
+am_gid=1000;     export am_gid
+run_configure
+checked "whether UID '$am_uid' is supported by ustar format" "no"
+checked "whether GID '1000' is supported by ustar format" "yes"
+checked "how to create a ustar tar archive" "none"
+
+# Another problematic ID reported in
+# <https://bugzilla.redhat.com/show_bug.cgi?id=843376>.
+am_uid=1000;     export am_uid
+am_gid=17000000; export am_gid
+run_configure
+checked "whether UID '1000' is supported by ustar format" "yes"
+checked "whether GID '$am_gid' is supported by ustar format" "no"
+checked "how to create a ustar tar archive" "none"
+
+# The minimal ID that is too big.
+two_to_twentyone=$((32 * 32 * 32 * 32 * 2))
+# <https://bugzilla.redhat.com/show_bug.cgi?id=843376>.
+am_uid=$two_to_twentyone; export am_uid
+am_gid=$two_to_twentyone; export am_gid
+run_configure
+checked "whether UID '$two_to_twentyone' is supported by ustar format" "no"
+checked "whether GID '$two_to_twentyone' is supported by ustar format" "no"
+checked "how to create a ustar tar archive" "none"
+
+:
diff --git a/t/tar.sh b/t/tar.sh
index 58e52ea..c146ad9 100755
--- a/t/tar.sh
+++ b/t/tar.sh
@@ -18,8 +18,8 @@
 
 . test-init.sh
 
-cat > configure.ac << 'END'
-AC_INIT([tar], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE([tar-ustar])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -32,9 +32,12 @@ $AUTOCONF
 $AUTOMAKE
 ./configure
 
-if grep 'am__tar.*false' Makefile; then
+grep 'am__tar' Makefile # For debugging.
+if grep '^am__tar = false' Makefile; then
   skip_ "cannot find proper archiver program"
 fi
 
 $MAKE distcheck
-test -f tar-1.0.tar.gz
+test -f "$distdir.tar.gz"
+
+:
diff --git a/t/tar2.sh b/t/tar2.sh
index 5a9d4d7..758d89a 100755
--- a/t/tar2.sh
+++ b/t/tar2.sh
@@ -18,8 +18,8 @@
 
 . test-init.sh
 
-cat > configure.ac << 'END'
-AC_INIT([tar2], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE([tar-pax])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -32,9 +32,12 @@ $AUTOCONF
 $AUTOMAKE
 ./configure
 
-if grep 'am__tar.*false' Makefile; then
+grep 'am__tar' Makefile # For debugging.
+if grep '^am__tar = false' Makefile; then
   skip_ "cannot find proper archiver program"
 fi
 
 $MAKE distcheck
-test -f tar2-1.0.tar.gz
+test -f "$distdir.tar.gz"
+
+:
diff --git a/t/tar3.sh b/t/tar3.sh
index 040d7b4..befc23f 100755
--- a/t/tar3.sh
+++ b/t/tar3.sh
@@ -18,8 +18,8 @@
 
 . test-init.sh
 
-cat > configure.ac << 'END'
-AC_INIT([tar2], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE([tar-pax tar-v7])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -37,8 +37,8 @@ grep "'tar-v7'"  tar-err
 
 rm -rf autom4te.cache
 
-cat > configure.ac << 'END'
-AC_INIT([tar2], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -47,6 +47,6 @@ END
 echo 'AUTOMAKE_OPTIONS = tar-pax' > Makefile.am
 
 AUTOMAKE_fails
-grep '^Makefile\.am:1:.*tar-pax.*AM_INIT_AUTOMAKE' stderr
+grep "^Makefile\.am:1:.*'tar-pax'.*AM_INIT_AUTOMAKE" stderr
 
 :
-- 
1.8.2.1.610.g562af5b

>From edfd3bc4c1057be0b5553b5789a44f1b77bb2b45 Mon Sep 17 00:00:00 2001
Message-Id: <edfd3bc4c[email-masked]>
From: Stefano Lattarini <[email-masked]>
Date: Sun, 17 Feb 2013 16:42:46 +0100
Subject: [PATCH] tar: format 'ustar' cannot support UID/GID longer than 21
 bits

See automake bug#8343 and bug#13588.

POSIX 1988 'ustar' format is defined with *fixed-size* fields. There
is notably a 21 bits limit (2097151) for the UID and the GID.

Tom Rini [email-masked] says (in bug#8343):

    When the user has a UID or GID that is larger than the ustar format
    supports, pax does not error out gracefully in some cases (FC13).

Marc Herbert <[email-masked]> adds (in bug#8343):

    When "configure" is run by a user with an UID bigger than 21 bits,
    BSD pax 3.4 aborts when trying to create the 'conftest.tar' test
    archive and leaves an empty or corrupted conftest.tar file behind.
    In the next step, pax tries to extract this incomplete or corrupted
    archive and this *** hangs the whole ./configure script ***.

    Note: GNU cpio 2.9 pretends to pass the test but it is a LIE: it
    silently truncates any big UID to its lower 21 bits. I don't know
    what can be the consequences of this lie.

    I think there is currently a design issue in automake/m4/tar.m4
    considering that a ustar archive should should *never* succeed when
    ./configure is run from a big user ID.

Months later, Petr Hracek <[email-masked]> reports a similar issue
(in bug#13588) for Fedora 17:

    I am trying to solve problem in case a user is created with big
    UID and during configuration pax hangs with message

        ATTENTION! pax archive volume change required.
        Ready for archive volume: 1
        Input archive name or "." to quit pax.
        Archive name >

    and needs user interaction.

    Reference: <https://bugzilla.redhat.com/show_bug.cgi?id=843376>

Time to fix this issue, on the line of a preliminary patch provided by
Petr Hracek in bug#13588.  The final patch ended up being remarkably
different from that original proposition, though.

* m4/tar.m4 (_AM_PROG_TAR): If the UID or GID of the current user is
too high (> 2097151), the 'ustar' format cannot work.  Adjust checks
accordingly.  Some related code reordering and clean-up.
* t/tar-ustar-id-too-high.sh: New test.
* t/list-of-tests.mk: Add it.
* t/tar.sh: While at it, tweak and enhance a little.
* t/tar2.sh: Likewise.
* t/tar3.sh: Likewise.
* t/tar-override.sh: Likewise.
* NEWS: Update.
* THANKS: Likewise.

Helped-by: Pavel Raiskup <[email-masked]>
Helped-by: Petr Hracek <[email-masked]>
Helped-by: Marc Herbert <[email-masked]>
Helped-by: Tom Rini <[email-masked]>
Signed-off-by: Stefano Lattarini <[email-masked]>
---
 NEWS                       |   6 ++
 THANKS                     |   3 +
 m4/tar.m4                  | 160 ++++++++++++++++++++++++++++-----------------
 t/list-of-tests.mk         |   1 +
 t/tar-override.sh          |  17 +++--
 t/tar-ustar-id-too-high.sh |  88 +++++++++++++++++++++++++
 t/tar.sh                   |  11 ++--
 t/tar2.sh                  |  11 ++--
 t/tar3.sh                  |  10 +--
 9 files changed, 226 insertions(+), 81 deletions(-)
 create mode 100755 t/tar-ustar-id-too-high.sh

diff --git a/NEWS b/NEWS
index f9a1fb1..863ffdf 100644
--- a/NEWS
+++ b/NEWS
@@ -78,6 +78,12 @@ New in 1.13.2:
 
 * Bugs fixed:
 
+  - When the 'ustar' option is used, the generated configure script no
+    longer risks hanging during the tests for the availability of the
+    'pax' utility, even if the user running configure has a UID or GID
+    that requires more than 21 bits to be represented.
+    See automake bug#8343 and bug#13588.
+
   - The obsolete macros AM_CONFIG_HEADER or AM_PROG_CC_STDC work once
     again, as they did in Automake 1.12.x (albeit printing runtime
     warnings in the 'obsolete' category).  Removing them has turned
diff --git a/THANKS b/THANKS
index 66498d4..a574909 100644
--- a/THANKS
+++ b/THANKS
@@ -224,6 +224,7 @@ Luo Yi                          [email-masked]
 Maciej Stachowiak               [email-masked]
 Maciej W. Rozycki               [email-masked]
 Manu Rouat                      [email-masked]
+Marc Herbert                    [email-masked]
 Marcus Brinkmann                [email-masked]
 Marcus G. Daniels               [email-masked]
 Marius Vollmer                  [email-masked]
@@ -311,6 +312,7 @@ Peter Muir                      [email-masked]
 Peter O'Gorman                  [email-masked]
 Peter Rosin                     [email-masked]
 Peter Seiderer                  [email-masked]
+Petr Hracek                     [email-masked]
 Petter Reinholdtsen             [email-masked]
 Petteri Räty                    [email-masked]
 Phil Edwards                    [email-masked]
@@ -391,6 +393,7 @@ Tim Rice                        [email-masked]
 Tim Van Holder                  [email-masked]
 Toshio Kuratomi                 [email-masked]
 Tom Epperly                     [email-masked]
+Tom Rini                        [email-masked]
 Ulrich Drepper                  [email-masked]
 Ulrich Eckhardt                 [email-masked]
 Václav Haisman                  [email-masked]
diff --git a/m4/tar.m4 b/m4/tar.m4
index ec8c83e..aac6d8f 100644
--- a/m4/tar.m4
+++ b/m4/tar.m4
@@ -19,76 +19,114 @@
 # Substitute a variable $(am__untar) that extract such
 # a tarball read from stdin.
 #     $(am__untar) < result.tar
+#
 AC_DEFUN([_AM_PROG_TAR],
 [# Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AC_SUBST([AMTAR], ['$${TAR-tar}'])
-m4_if([$1], [v7],
-     [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
-     [m4_case([$1], [ustar],, [pax],,
-              [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
+
+# We'll loop over all known methods to create a tar archive until one works.
 _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of '-'.
-for _am_tool in $_am_tools
-do
-  case $_am_tool in
-  gnutar)
-    for _am_tar in tar gnutar gtar;
-    do
-      AM_RUN_LOG([$_am_tar --version]) && break
-    done
-    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
-    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
-    am__untar="$_am_tar -xf -"
-    ;;
-  plaintar)
-    # Must skip GNU tar: if it does not support --format= it doesn't create
-    # ustar tarball either.
-    (tar --version) >/dev/null 2>&1 && continue
-    am__tar='tar chf - "$$tardir"'
-    am__tar_='tar chf - "$tardir"'
-    am__untar='tar xf -'
-    ;;
-  pax)
-    am__tar='pax -L -x $1 -w "$$tardir"'
-    am__tar_='pax -L -x $1 -w "$tardir"'
-    am__untar='pax -r'
-    ;;
-  cpio)
-    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
-    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
-    am__untar='cpio -i -H $1 -d'
-    ;;
-  none)
-    am__tar=false
-    am__tar_=false
-    am__untar=false
-    ;;
-  esac
 
-  # If the value was cached, stop now.  We just wanted to have am__tar
-  # and am__untar set.
-  test -n "${am_cv_prog_tar_$1}" && break
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
 
-  # tar/untar a dummy directory, and stop if the command works
-  rm -rf conftest.dir
-  mkdir conftest.dir
-  echo GrepMe > conftest.dir/file
-  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
+
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
   rm -rf conftest.dir
-  if test -s conftest.tar; then
-    AM_RUN_LOG([$am__untar <conftest.tar])
-    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
-  fi
-done
-rm -rf conftest.dir
 
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+  
 AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index f1e3dca..664a902 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -1151,6 +1151,7 @@ t/tags-pr12372.sh \
 t/tar.sh \
 t/tar2.sh \
 t/tar3.sh \
+t/tar-ustar-id-too-high.sh \
 t/tar-override.sh \
 t/target-cflags.sh \
 t/targetclash.sh \
diff --git a/t/tar-override.sh b/t/tar-override.sh
index 863b9ab..bbf3fbb 100755
--- a/t/tar-override.sh
+++ b/t/tar-override.sh
@@ -16,8 +16,8 @@
 
 # Check that the user can override the tar program used by "make dist"
 # at runtime, by redefining the 'TAR' environment variable.
-# FIXME: currently this works only when the tar format used is 'v7'
-# FIXME: (which is the default one).
+# NOTE: currently this works only when the tar format used is 'v7'
+#       (which is the default one).
 
 . test-init.sh
 
@@ -35,6 +35,7 @@ chmod a+x am--tar
 
 cat > Makefile.am <<'END'
 check-local: dist
+	ls -l ;: For debugging.
 	test -f am--tar-has-run
 CLEANFILES = am--tar-has-run
 END
@@ -44,22 +45,24 @@ $AUTOCONF
 $AUTOMAKE
 ./configure
 
+clean_temp () { rm -f *.tar.* *has-run*; }
+
 $MAKE dist
-test -f $me-1.0.tar.gz
+test -f $distdir.tar.gz
 ls | grep has-run && exit 1
 
-rm -f *.tar.* *has-run*
+clean_temp
 
 TAR="$cwd/am--tar foo" $MAKE distcheck
-test -f $me-1.0.tar.gz
+test -f $distdir.tar.gz
 test "$(cat am--tar-has-run)" = foo
 
-rm -f *.tar.* *has-run*
+clean_temp
 
 TAR=; unset TAR
 # Creative use of eval to pacify maintainer checks.
 eval \$'MAKE dist "TAR=./am--tar mu"'
-test -f $me-1.0.tar.gz
+test -f $distdir.tar.gz
 test "$(cat am--tar-has-run)" = mu
 
 :
diff --git a/t/tar-ustar-id-too-high.sh b/t/tar-ustar-id-too-high.sh
new file mode 100755
index 0000000..79ae89d
--- /dev/null
+++ b/t/tar-ustar-id-too-high.sh
@@ -0,0 +1,88 @@
+#! /bin/sh
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Check that UID or GID too high for the ustar format are correctly
+# rwcognized and diagnosed by configure.  See bug#8343 and bug#13588.
+
+. test-init.sh
+
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
+AM_INIT_AUTOMAKE([tar-ustar])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+END
+
+: > Makefile.am
+
+run_configure()
+{
+  st=0; ./configure ${1+"$@"}  >stdout || st=$?
+  cat stdout || exit 1
+  test $st -eq 0 || exit 1
+}
+
+checked ()
+{
+  grep "^checking $1\.\.\. $2$" stdout
+}
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+mkdir bin
+cat > bin/id <<'END'
+#!/bin/sh -e
+case "$*" in
+  -u) echo "${am_uid-1000}";;
+  -g) echo "${am_gid-1000}";;
+   *) echo "id: bad/unexpected usage" >&2; exit 1;;
+esac
+END
+chmod a+x bin/id
+
+PATH=$(pwd)/bin$PATH_SEPARATOR$PATH
+
+# Problematic ID reported in
+# <https://bugzilla.redhat.com/show_bug.cgi?id=843376>.
+am_uid=16777216; export am_uid
+am_gid=1000;     export am_gid
+run_configure
+checked "whether UID '$am_uid' is supported by ustar format" "no"
+checked "whether GID '1000' is supported by ustar format" "yes"
+checked "how to create a ustar tar archive" "none"
+
+# Another problematic ID reported in
+# <https://bugzilla.redhat.com/show_bug.cgi?id=843376>.
+am_uid=1000;     export am_uid
+am_gid=17000000; export am_gid
+run_configure
+checked "whether UID '1000' is supported by ustar format" "yes"
+checked "whether GID '$am_gid' is supported by ustar format" "no"
+checked "how to create a ustar tar archive" "none"
+
+# The minimal ID that is too big.
+two_to_twentyone=$((32 * 32 * 32 * 32 * 2))
+# <https://bugzilla.redhat.com/show_bug.cgi?id=843376>.
+am_uid=$two_to_twentyone; export am_uid
+am_gid=$two_to_twentyone; export am_gid
+run_configure
+checked "whether UID '$two_to_twentyone' is supported by ustar format" "no"
+checked "whether GID '$two_to_twentyone' is supported by ustar format" "no"
+checked "how to create a ustar tar archive" "none"
+
+:
diff --git a/t/tar.sh b/t/tar.sh
index 58e52ea..c146ad9 100755
--- a/t/tar.sh
+++ b/t/tar.sh
@@ -18,8 +18,8 @@
 
 . test-init.sh
 
-cat > configure.ac << 'END'
-AC_INIT([tar], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE([tar-ustar])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -32,9 +32,12 @@ $AUTOCONF
 $AUTOMAKE
 ./configure
 
-if grep 'am__tar.*false' Makefile; then
+grep 'am__tar' Makefile # For debugging.
+if grep '^am__tar = false' Makefile; then
   skip_ "cannot find proper archiver program"
 fi
 
 $MAKE distcheck
-test -f tar-1.0.tar.gz
+test -f "$distdir.tar.gz"
+
+:
diff --git a/t/tar2.sh b/t/tar2.sh
index 5a9d4d7..758d89a 100755
--- a/t/tar2.sh
+++ b/t/tar2.sh
@@ -18,8 +18,8 @@
 
 . test-init.sh
 
-cat > configure.ac << 'END'
-AC_INIT([tar2], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE([tar-pax])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -32,9 +32,12 @@ $AUTOCONF
 $AUTOMAKE
 ./configure
 
-if grep 'am__tar.*false' Makefile; then
+grep 'am__tar' Makefile # For debugging.
+if grep '^am__tar = false' Makefile; then
   skip_ "cannot find proper archiver program"
 fi
 
 $MAKE distcheck
-test -f tar2-1.0.tar.gz
+test -f "$distdir.tar.gz"
+
+:
diff --git a/t/tar3.sh b/t/tar3.sh
index 040d7b4..befc23f 100755
--- a/t/tar3.sh
+++ b/t/tar3.sh
@@ -18,8 +18,8 @@
 
 . test-init.sh
 
-cat > configure.ac << 'END'
-AC_INIT([tar2], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE([tar-pax tar-v7])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -37,8 +37,8 @@ grep "'tar-v7'"  tar-err
 
 rm -rf autom4te.cache
 
-cat > configure.ac << 'END'
-AC_INIT([tar2], [1.0])
+cat > configure.ac <<END
+AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -47,6 +47,6 @@ END
 echo 'AUTOMAKE_OPTIONS = tar-pax' > Makefile.am
 
 AUTOMAKE_fails
-grep '^Makefile\.am:1:.*tar-pax.*AM_INIT_AUTOMAKE' stderr
+grep "^Makefile\.am:1:.*'tar-pax'.*AM_INIT_AUTOMAKE" stderr
 
 :
-- 
1.8.2.1.610.g562af5b