Bugfix(sftp): fix loose permissions on sftp backend. (#5497)

This commit is contained in:
Rani
2025-10-03 21:20:52 +03:00
committed by GitHub
parent 264cd67c36
commit 3ae6a69154
2 changed files with 25 additions and 1 deletions

View File

@@ -0,0 +1,8 @@
Bugfix: Mark files as readonly when using the SFTP backend
Files created by the SFTP backend previously allowed writes to those files.
Restic now restricts the file permissions on SFTP backend to readonly.
This change only has an effect for sftp servers with support for the chmod operation.
https://github.com/restic/restic/issues/5487
https://github.com/restic/restic/pull/5497

View File

@@ -287,6 +287,18 @@ func tempSuffix() string {
return hex.EncodeToString(nonce[:])
}
func setFileReadonly(client *sftp.Client, path string, mode os.FileMode) error {
// clear owner/group/other write bits
readonlyMode := mode &^ 0o222
err := client.Chmod(path, readonlyMode)
// if the operation is not supported in the sftp server we ignore it.
if errors.Is(err, sftp.ErrSSHFxOpUnsupported) {
return nil
}
return err
}
// Save stores data in the backend at the handle.
func (r *SFTP) Save(_ context.Context, h backend.Handle, rd backend.RewindReader) error {
if err := r.clientError(); err != nil {
@@ -350,7 +362,6 @@ func (r *SFTP) Save(_ context.Context, h backend.Handle, rd backend.RewindReader
_ = f.Close()
return errors.Errorf("Write %v: wrote %d bytes instead of the expected %d bytes", tmpFilename, wbytes, rd.Length())
}
err = f.Close()
if err != nil {
return errors.Wrapf(err, "Close %v", tmpFilename)
@@ -362,6 +373,11 @@ func (r *SFTP) Save(_ context.Context, h backend.Handle, rd backend.RewindReader
} else {
err = r.c.Rename(tmpFilename, filename)
}
err = setFileReadonly(r.c, filename, r.Modes.File)
if err != nil {
return errors.Errorf("sftp setFileReadonly: %v", err)
}
return errors.Wrapf(err, "Rename %v", tmpFilename)
}