From 10fa5cde0a29476cfcfbd0a4fc597563792c3de7 Mon Sep 17 00:00:00 2001 From: Panagiotis Cheilaris Date: Tue, 27 Dec 2022 16:36:04 +0100 Subject: [PATCH] in tar dump, convert uid, gid of value -1 to zero --- changelog/unreleased/issue-4103 | 12 ++++++++++++ internal/dump/tar.go | 13 +++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 changelog/unreleased/issue-4103 diff --git a/changelog/unreleased/issue-4103 b/changelog/unreleased/issue-4103 new file mode 100644 index 000000000..78d0b2ae1 --- /dev/null +++ b/changelog/unreleased/issue-4103 @@ -0,0 +1,12 @@ +Bugfix: fix restic dump of tar file with 32-bit binary + +In restic up to 0.14.0, the restic dump from a 32-bit binary of a +snapshot of standard input that was created in Windows has as a +result a tar file whose content has a negative uid and gid. As a +result, gnu tar exits with failure status whenever it tries to +access such a tar file. With this fix, the tar file that is now +dumped from a 32-bit binary has content with non-negative uid and +gid. + +https://github.com/restic/restic/issues/4103 +https://github.com/restic/restic/pull/4104 diff --git a/internal/dump/tar.go b/internal/dump/tar.go index 65b68ee5b..0e4b83290 100644 --- a/internal/dump/tar.go +++ b/internal/dump/tar.go @@ -3,6 +3,7 @@ package dump import ( "archive/tar" "context" + "math" "os" "path/filepath" "strings" @@ -38,6 +39,14 @@ const ( cISVTX = 0o1000 // Save text (sticky bit) ) +// substitute a uid or gid of -1 (which is converted to 2^32 - 1) with zero +func tarId(id uint32) int { + if id == math.MaxUint32 { + return 0 + } + return int(id) +} + func (d *Dumper) dumpNodeTar(ctx context.Context, node *restic.Node, w *tar.Writer) error { relPath, err := filepath.Rel("/", node.Path) if err != nil { @@ -48,8 +57,8 @@ func (d *Dumper) dumpNodeTar(ctx context.Context, node *restic.Node, w *tar.Writ Name: filepath.ToSlash(relPath), Size: int64(node.Size), Mode: int64(node.Mode.Perm()), // cIS* constants are added later - Uid: int(node.UID), - Gid: int(node.GID), + Uid: tarId(node.UID), + Gid: tarId(node.GID), Uname: node.User, Gname: node.Group, ModTime: node.ModTime,