summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2003-02-24 11:58:44 +1100
committerDamien Miller <djm@mindrot.org>2003-02-24 11:58:44 +1100
commit9e51a73122fdb06c14068017d8f2a04179bf6bf6 (patch)
treea3d6a177b5e76ec09ff24d0fe6c0d71f42d6e6a9
parent9f1e33a6b295f46dba45b0eefac173f699480943 (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--ChangeLog5
-rw-r--r--sftp-server.c28
2 files changed, 18 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 9003211e..7db7cf59 100644
--- 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
@@ -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);