]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
- markus@cvs.openbsd.org 2003/02/06 09:29:18
authorDamien Miller <djm@mindrot.org>
Mon, 24 Feb 2003 00:58:44 +0000 (11:58 +1100)
committerDamien Miller <djm@mindrot.org>
Mon, 24 Feb 2003 00:58:44 +0000 (11:58 +1100)
     [sftp-server.c]
     fix races in rename/symlink; from Tony Finch; ok djm@

ChangeLog
sftp-server.c

index 9003211e6f8d3f32296bc137133eec37acf85c36..7db7cf594a92bc8920c9d0ad8e938a48048e986d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
      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 $
index 84264693d73aeab364eedf8d0a0232e058f77334..4eb31d94e2ebad34315ca7d4ea6221d9db181e68 100644 (file)
@@ -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);