diff options
author | Damien Miller <djm@mindrot.org> | 2003-02-24 11:58:44 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2003-02-24 11:58:44 +1100 |
commit | 9e51a73122fdb06c14068017d8f2a04179bf6bf6 (patch) | |
tree | a3d6a177b5e76ec09ff24d0fe6c0d71f42d6e6a9 | |
parent | 9f1e33a6b295f46dba45b0eefac173f699480943 (diff) |
- markus@cvs.openbsd.org 2003/02/06 09:29:18
[sftp-server.c]
fix races in rename/symlink; from Tony Finch; ok djm@
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sftp-server.c | 28 |
2 files changed, 18 insertions, 15 deletions
@@ -48,6 +48,9 @@ - markus@cvs.openbsd.org 2003/02/06 09:27:29 [ssh.c ssh_config.5] support 'ProxyCommand none'; bugzilla #433; binder@arago.de; ok djm@ + - markus@cvs.openbsd.org 2003/02/06 09:29:18 + [sftp-server.c] + fix races in rename/symlink; from Tony Finch; ok djm@ 20030211 - (djm) Cygwin needs libcrypt too. Patch from vinschen@redhat.com @@ -1148,4 +1151,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2606 2003/02/24 00:57:32 djm Exp $ +$Id: ChangeLog,v 1.2607 2003/02/24 00:58:44 djm Exp $ diff --git a/sftp-server.c b/sftp-server.c index 84264693..4eb31d94 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: sftp-server.c,v 1.38 2002/09/11 22:41:50 djm Exp $"); +RCSID("$OpenBSD: sftp-server.c,v 1.39 2003/02/06 09:29:18 markus Exp $"); #include "buffer.h" #include "bufaux.h" @@ -832,19 +832,22 @@ static void process_rename(void) { u_int32_t id; - struct stat st; char *oldpath, *newpath; - int ret, status = SSH2_FX_FAILURE; + int status; id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); TRACE("rename id %u old %s new %s", id, oldpath, newpath); /* fail if 'newpath' exists */ - if (stat(newpath, &st) == -1) { - ret = rename(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + if (link(oldpath, newpath) == -1) + status = errno_to_portable(errno); + else if (unlink(oldpath) == -1) { + status = errno_to_portable(errno); + /* clean spare link */ + unlink(newpath); + } else + status = SSH2_FX_OK; send_status(id, status); xfree(oldpath); xfree(newpath); @@ -878,19 +881,16 @@ static void process_symlink(void) { u_int32_t id; - struct stat st; char *oldpath, *newpath; - int ret, status = SSH2_FX_FAILURE; + int ret, status; id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); TRACE("symlink id %u old %s new %s", id, oldpath, newpath); - /* fail if 'newpath' exists */ - if (stat(newpath, &st) == -1) { - ret = symlink(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; - } + /* this will fail if 'newpath' exists */ + ret = symlink(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); xfree(oldpath); xfree(newpath); |