mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-27 07:44:29 +02:00
upstream: increase maximum SSH2_FXP_READ to match the maximum
packet size. Also handle zero-length reads that are borderline nonsensical but not explicitly banned by the spec. Based on patch from Mike Frysinger, feedback deraadt@ ok dtucker@ OpenBSD-Commit-ID: 4e67d60d81bde7b84a742b4ee5a34001bdf80d9c
This commit is contained in:
parent
860b676044
commit
1269b8a686
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: sftp-server.c,v 1.123 2021/03/16 06:15:43 djm Exp $ */
|
/* $OpenBSD: sftp-server.c,v 1.124 2021/03/19 02:18:28 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -55,7 +55,7 @@
|
|||||||
char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
|
char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
|
||||||
|
|
||||||
/* Maximum data read that we are willing to accept */
|
/* Maximum data read that we are willing to accept */
|
||||||
#define SFTP_MAX_READ_LENGTH (64 * 1024)
|
#define SFTP_MAX_READ_LENGTH (SFTP_MAX_MSG_LENGTH - 1024)
|
||||||
|
|
||||||
/* Our verbosity */
|
/* Our verbosity */
|
||||||
static LogLevel log_level = SYSLOG_LEVEL_ERROR;
|
static LogLevel log_level = SYSLOG_LEVEL_ERROR;
|
||||||
@ -748,7 +748,8 @@ process_close(u_int32_t id)
|
|||||||
static void
|
static void
|
||||||
process_read(u_int32_t id)
|
process_read(u_int32_t id)
|
||||||
{
|
{
|
||||||
u_char buf[SFTP_MAX_READ_LENGTH];
|
static u_char *buf;
|
||||||
|
static size_t buflen;
|
||||||
u_int32_t len;
|
u_int32_t len;
|
||||||
int r, handle, fd, ret, status = SSH2_FX_FAILURE;
|
int r, handle, fd, ret, status = SSH2_FX_FAILURE;
|
||||||
u_int64_t off;
|
u_int64_t off;
|
||||||
@ -758,30 +759,43 @@ process_read(u_int32_t id)
|
|||||||
(r = sshbuf_get_u32(iqueue, &len)) != 0)
|
(r = sshbuf_get_u32(iqueue, &len)) != 0)
|
||||||
fatal_fr(r, "parse");
|
fatal_fr(r, "parse");
|
||||||
|
|
||||||
debug("request %u: read \"%s\" (handle %d) off %llu len %d",
|
debug("request %u: read \"%s\" (handle %d) off %llu len %u",
|
||||||
id, handle_to_name(handle), handle, (unsigned long long)off, len);
|
id, handle_to_name(handle), handle, (unsigned long long)off, len);
|
||||||
if (len > sizeof buf) {
|
if ((fd = handle_to_fd(handle)) == -1)
|
||||||
len = sizeof buf;
|
goto out;
|
||||||
debug2("read change len %d", len);
|
if (len > SFTP_MAX_READ_LENGTH) {
|
||||||
|
debug2("read change len %u to %u", len, SFTP_MAX_READ_LENGTH);
|
||||||
|
len = SFTP_MAX_READ_LENGTH;
|
||||||
}
|
}
|
||||||
fd = handle_to_fd(handle);
|
if (len > buflen) {
|
||||||
if (fd >= 0) {
|
debug3_f("allocate %zu => %u", buflen, len);
|
||||||
if (lseek(fd, off, SEEK_SET) == -1) {
|
if ((buf = realloc(NULL, len)) == NULL)
|
||||||
error("process_read: seek failed");
|
fatal_f("realloc failed");
|
||||||
status = errno_to_portable(errno);
|
buflen = len;
|
||||||
} else {
|
|
||||||
ret = read(fd, buf, len);
|
|
||||||
if (ret == -1) {
|
|
||||||
status = errno_to_portable(errno);
|
|
||||||
} else if (ret == 0) {
|
|
||||||
status = SSH2_FX_EOF;
|
|
||||||
} else {
|
|
||||||
send_data(id, buf, ret);
|
|
||||||
status = SSH2_FX_OK;
|
|
||||||
handle_update_read(handle, ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (lseek(fd, off, SEEK_SET) == -1) {
|
||||||
|
status = errno_to_portable(errno);
|
||||||
|
error_f("seek \"%.100s\": %s", handle_to_name(handle),
|
||||||
|
strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (len == 0) {
|
||||||
|
/* weird, but not strictly disallowed */
|
||||||
|
ret = 0;
|
||||||
|
} else if ((ret = read(fd, buf, len)) == -1) {
|
||||||
|
status = errno_to_portable(errno);
|
||||||
|
error_f("read \"%.100s\": %s", handle_to_name(handle),
|
||||||
|
strerror(errno));
|
||||||
|
goto out;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
status = SSH2_FX_EOF;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
send_data(id, buf, ret);
|
||||||
|
handle_update_read(handle, ret);
|
||||||
|
/* success */
|
||||||
|
status = SSH2_FX_OK;
|
||||||
|
out:
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
send_status(id, status);
|
send_status(id, status);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user