mirror of
https://github.com/openbsd/src.git
synced 2026-06-18 07:13:36 +02:00
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@
This commit is contained in:
@@ -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.
|
||||
*
|
||||
@@ -1581,6 +1581,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 ||
|
||||
@@ -1603,12 +1604,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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user