From 40ee17167e36553b2773a6b2e65a5a2158099f56 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Tue, 6 Oct 2020 18:28:01 +0200 Subject: [PATCH 1/3] local: Ignore permission errors on chmod call in Save/Remove operation The file is already created with the proper permissions, thus the chmod call is not critical. However, some file systems have don't allow modifications of the file permissions. Similarly the chmod call in the Remove operation should not prevent it from working. --- internal/backend/local/local.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/backend/local/local.go b/internal/backend/local/local.go index 19f083a29..675c4a08d 100644 --- a/internal/backend/local/local.go +++ b/internal/backend/local/local.go @@ -130,7 +130,14 @@ func (b *Local) Save(ctx context.Context, h restic.Handle, rd restic.RewindReade return errors.Wrap(err, "Close") } - return setNewFileMode(filename, backend.Modes.File) + // ignore if the operation fails as some filesystems don't allow the chmod call + // e.g. exfat and network file systems with certain mount options + err = setNewFileMode(filename, backend.Modes.File) + if err != nil && !os.IsPermission(err) { + return errors.Wrap(err, "Chmod") + } + + return nil } // Load runs fn with a reader that yields the contents of the file at h at the @@ -205,7 +212,7 @@ func (b *Local) Remove(ctx context.Context, h restic.Handle) error { // reset read-only flag err := fs.Chmod(fn, 0666) - if err != nil { + if err != nil && !os.IsPermission(err) { return errors.Wrap(err, "Chmod") } From f4282aa6fdf87cf89a3518d91d42f5bc4776af50 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Tue, 6 Oct 2020 18:46:19 +0200 Subject: [PATCH 2/3] local: mark repository files as read-only This is intended to prevent accidental modifications of data files. Marking the files as read-only was accidentally removed in #1258. --- internal/backend/local/local.go | 3 ++- internal/backend/local/local_unix.go | 4 ++-- internal/backend/local/local_windows.go | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/backend/local/local.go b/internal/backend/local/local.go index 675c4a08d..34ac3a20e 100644 --- a/internal/backend/local/local.go +++ b/internal/backend/local/local.go @@ -130,9 +130,10 @@ func (b *Local) Save(ctx context.Context, h restic.Handle, rd restic.RewindReade return errors.Wrap(err, "Close") } + // try to mark file as read-only to avoid accidential modifications // ignore if the operation fails as some filesystems don't allow the chmod call // e.g. exfat and network file systems with certain mount options - err = setNewFileMode(filename, backend.Modes.File) + err = setFileReadonly(filename, backend.Modes.File) if err != nil && !os.IsPermission(err) { return errors.Wrap(err, "Chmod") } diff --git a/internal/backend/local/local_unix.go b/internal/backend/local/local_unix.go index 74fb47bf4..cc99d4a0b 100644 --- a/internal/backend/local/local_unix.go +++ b/internal/backend/local/local_unix.go @@ -9,6 +9,6 @@ import ( ) // set file to readonly -func setNewFileMode(f string, mode os.FileMode) error { - return fs.Chmod(f, mode) +func setFileReadonly(f string, mode os.FileMode) error { + return fs.Chmod(f, mode&^0222) } diff --git a/internal/backend/local/local_windows.go b/internal/backend/local/local_windows.go index be8f62d96..ccf788072 100644 --- a/internal/backend/local/local_windows.go +++ b/internal/backend/local/local_windows.go @@ -7,6 +7,6 @@ import ( // We don't modify read-only on windows, // since it will make us unable to delete the file, // and this isn't common practice on this platform. -func setNewFileMode(f string, mode os.FileMode) error { +func setFileReadonly(f string, mode os.FileMode) error { return nil } From bc65da2baf2e070a94a1b6235a457f1b4b4a231b Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Mon, 5 Oct 2020 22:54:35 +0200 Subject: [PATCH 3/3] Add changelog --- changelog/unreleased/issue-1756 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 changelog/unreleased/issue-1756 diff --git a/changelog/unreleased/issue-1756 b/changelog/unreleased/issue-1756 new file mode 100644 index 000000000..f735cf1f9 --- /dev/null +++ b/changelog/unreleased/issue-1756 @@ -0,0 +1,15 @@ +Bugfix: Mark repository files as read-only when using the local backend + +Files stored in a local repository were marked as writeable on the +filesystem for non-Windows systems, which did not prevent accidental file +modifications outside of restic. In addition, the local backend did not work +with certain filesystems and network mounts which do not permit modifications +of file permissions. + +restic now marks files stored in a local repository as read-only on the +filesystem on non-Windows systems. The error handling is improved to support +more filesystems. + +https://github.com/restic/restic/issues/1756 +https://github.com/restic/restic/issues/2157 +https://github.com/restic/restic/pull/2989