diff options
author | djm@openbsd.org <djm@openbsd.org> | 2022-05-16 01:47:21 +0200 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2022-05-16 14:56:58 +0200 |
commit | 9b73345f80255a7f3048026462f2c0c6a241eeac (patch) | |
tree | 43b5b2b78fbc78abd867f7fb364498be061e9ca8 /sftp-client.c | |
parent | upstream: arrange for scp, when in sftp mode, to not ftruncate(3) files (diff) | |
download | openssh-9b73345f80255a7f3048026462f2c0c6a241eeac.tar.xz openssh-9b73345f80255a7f3048026462f2c0c6a241eeac.zip |
upstream: fix in-place copies; r1.163 incorrectly skipped truncation in
all cases, not just at the start of a transfer. This could cause overwrites
of larger files to leave junk at the end. Spotted by tb@
OpenBSD-Commit-ID: b189f19cd68119548c8e24e39c79f61e115bf92c
Diffstat (limited to 'sftp-client.c')
-rw-r--r-- | sftp-client.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/sftp-client.c b/sftp-client.c index dffb35a2f..310d44e5e 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.163 2022/05/13 06:31:50 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.164 2022/05/15 23:47:21 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> * @@ -1789,8 +1789,11 @@ do_download(struct sftp_conn *conn, const char *remote_path, /* Sanity check */ if (TAILQ_FIRST(&requests) != NULL) fatal("Transfer complete, but requests still in queue"); - /* Truncate at highest contiguous point to avoid holes on interrupt */ - if (read_error || write_error || interrupted) { + /* + * Truncate at highest contiguous point to avoid holes on interrupt, + * or unconditionally if writing in place. + */ + if (inplace_flag || read_error || write_error || interrupted) { if (reordered && resume_flag) { error("Unable to resume download of \"%s\": " "server reordered requests", local_path); @@ -2156,12 +2159,12 @@ do_upload(struct sftp_conn *conn, const char *local_path, status = SSH2_FX_FAILURE; } - if ((resume || inplace_flag) && (status != SSH2_FX_OK || interrupted)) { + if (inplace_flag || (resume && (status != SSH2_FX_OK || interrupted))) { debug("truncating at %llu", (unsigned long long)highwater); attrib_clear(&t); t.flags = SSH2_FILEXFER_ATTR_SIZE; t.size = highwater; - do_fsetstat(conn, handle, handle_len, &a); + do_fsetstat(conn, handle, handle_len, &t); } if (close(local_fd) == -1) { |