[openssh-commits] [openssh] 08/08: upstream: disallow use of the copy-data extension to read and write

git+noreply at mindrot.org git+noreply at mindrot.org
Sun May 31 15:04:11 AEST 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 5a5e47740b6466d58242aca28b9e584bab4ccf1d
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Sun May 31 04:59:51 2026 +0000

    upstream: disallow use of the copy-data extension to read and write
    
    to the same inode simultaneously; reported by Qifan Zhang of Palo Alto
    Networks; ok markus@
    
    OpenBSD-Commit-ID: 94ceb85146d92dbc1289c55d308498d5f56f274a
---
 sftp-server.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/sftp-server.c b/sftp-server.c
index ebdb31d32..ed57339d5 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server.c,v 1.153 2026/03/03 09:57:25 dtucker Exp $ */
+/* $OpenBSD: sftp-server.c,v 1.154 2026/05/31 04:59:51 djm Exp $ */
 /*
  * Copyright (c) 2000-2004 Markus Friedl.  All rights reserved.
  *
@@ -1606,6 +1606,7 @@ process_extended_copy_data(uint32_t id)
 	uint64_t len, read_off, read_len, write_off;
 	int r, copy_until_eof, status = SSH2_FX_OP_UNSUPPORTED;
 	size_t ret;
+	struct stat st_read, st_write;
 
 	if ((r = get_handle(iqueue, &read_handle)) != 0 ||
 	    (r = sshbuf_get_u64(iqueue, &read_off)) != 0 ||
@@ -1628,12 +1629,30 @@ process_extended_copy_data(uint32_t id)
 	} else
 		copy_until_eof = 0;
 
+	/* Disallow reading & writing to the same handle, path or inode */
 	read_fd = handle_to_fd(read_handle);
 	write_fd = handle_to_fd(write_handle);
-
-	/* Disallow reading & writing to the same handle or same path or dirs */
+	if (fstat(read_fd, &st_read) != 0) {
+		status = errno_to_portable(errno);
+		error_f("fstat read_fd failed: %s", strerror(errno));
+		goto out;
+	}
+	if (fstat(write_fd, &st_write) != 0) {
+		status = errno_to_portable(errno);
+		error_f("fstat write_fd failed: %s", strerror(errno));
+		goto out;
+	}
 	if (read_handle == write_handle || read_fd < 0 || write_fd < 0 ||
-	    !strcmp(handle_to_name(read_handle), handle_to_name(write_handle))) {
+	    !strcmp(handle_to_name(read_handle), handle_to_name(write_handle)) ||
+	    (st_read.st_dev != 0 && st_read.st_ino != 0 &&
+	    st_read.st_dev == st_write.st_dev &&
+	    st_read.st_ino == st_write.st_ino)) {
+		error_f("refusing to read/write same file: "
+		    "read \"%s\" dev %lu ino %lu, write \"%s\" dev %lu ino %lu",
+		    handle_to_name(read_handle),
+		    (u_long)st_read.st_dev, (u_long)st_read.st_ino,
+		    handle_to_name(write_handle),
+		    (u_long)st_write.st_dev, (u_long)st_write.st_ino);
 		status = SSH2_FX_FAILURE;
 		goto out;
 	}

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list