diff --git a/changelog/unreleased/issue-4103 b/changelog/unreleased/issue-4103 new file mode 100644 index 000000000..5b152f992 --- /dev/null +++ b/changelog/unreleased/issue-4103 @@ -0,0 +1,9 @@ +Bugfix: fix restic dump of tar file with 32-bit binary + +When using a 32-bit build of restic, the `restic dump` command could in some +cases create tar files containing negative uid and gid. These files cannot be +read by gnu tar. This corner case especially applies to backups from stdin on Windows. +We have changed the dump command to create valid tar files in this case. + +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..6e87aabe5 100644 --- a/internal/dump/tar.go +++ b/internal/dump/tar.go @@ -38,6 +38,15 @@ const ( cISVTX = 0o1000 // Save text (sticky bit) ) +// in a 32-bit build of restic: +// substitute a uid or gid of -1 (which was converted to 2^32 - 1) with 0 +func tarIdentifier(id uint32) int { + if int(id) == -1 { + 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: tarIdentifier(node.UID), + Gid: tarIdentifier(node.GID), Uname: node.User, Gname: node.Group, ModTime: node.ModTime,