From 5eb9e6896e64d385b4d68c35f7424db63c4f48c7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Mar 2026 12:25:13 +0100 Subject: [PATCH] sftpserver: Check return value of sftp_client_message_get_filename() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Originally reported by nevv. Signed-off-by: Jakub Jelen Reviewed-by: Pavol Žáčik --- src/sftpserver.c | 72 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/sftpserver.c b/src/sftpserver.c index b5b98e05..fce54a0a 100644 --- a/src/sftpserver.c +++ b/src/sftpserver.c @@ -376,6 +376,9 @@ const char *sftp_client_message_get_filename(sftp_client_message msg) * * @param[in] msg The SFTP client message to modify. * @param[in] newname The new filename to store in the message. + * + * @warn On failure, the filename in the message is set to `NULL`. Users of + * sftp_client_message_get_filename() need to check the return value! */ void sftp_client_message_set_filename(sftp_client_message msg, const char *newname) @@ -1497,6 +1500,12 @@ process_open(sftp_client_message client_msg) int fd = -1; int status; + if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); + sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); + return SSH_ERROR; + } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing open: filename %s, mode=0%o" PRIu32, filename, mode); @@ -1728,6 +1737,12 @@ process_opendir(sftp_client_message client_msg) ssh_string handle_s = NULL; struct sftp_handle *h = NULL; + if (dir_name == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing dir_name from in message"); + sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); + return SSH_ERROR; + } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing opendir %s", dir_name); dir = opendir(dir_name); @@ -1954,14 +1969,15 @@ process_mkdir(sftp_client_message client_msg) int status = SSH_FX_OK; int rv; - SSH_LOG(SSH_LOG_PROTOCOL, "Processing mkdir %s, mode=0%o" PRIu32, - filename, mode); - if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); return SSH_ERROR; } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing mkdir %s, mode=0%o" PRIu32, + filename, mode); + rv = mkdir(filename, mode); if (rv < 0) { int saved_errno = errno; @@ -1983,13 +1999,14 @@ process_rmdir(sftp_client_message client_msg) int status = SSH_FX_OK; int rv; - SSH_LOG(SSH_LOG_PROTOCOL, "Processing rmdir %s", filename); - if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); return SSH_ERROR; } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing rmdir %s", filename); + rv = rmdir(filename); if (rv < 0) { status = unix_errno_to_ssh_stat(errno); @@ -2007,6 +2024,12 @@ process_realpath(sftp_client_message client_msg) const char *filename = sftp_client_message_get_filename(client_msg); char *path = NULL; + if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); + sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); + return SSH_ERROR; + } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing realpath %s", filename); if (filename[0] == '\0') { @@ -2038,13 +2061,14 @@ process_lstat(sftp_client_message client_msg) int status = SSH_FX_OK; int rv; - SSH_LOG(SSH_LOG_PROTOCOL, "Processing lstat %s", filename); - if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); return SSH_ERROR; } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing lstat %s", filename); + rv = lstat(filename, &st); if (rv < 0) { int saved_errno = errno; @@ -2070,13 +2094,14 @@ process_stat(sftp_client_message client_msg) int status = SSH_FX_OK; int rv; - SSH_LOG(SSH_LOG_PROTOCOL, "Processing stat %s", filename); - if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); return SSH_ERROR; } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing stat %s", filename); + rv = stat(filename, &st); if (rv < 0) { int saved_errno = errno; @@ -2101,13 +2126,14 @@ process_setstat(sftp_client_message client_msg) uint32_t msg_flags = client_msg->attr->flags; const char *filename = sftp_client_message_get_filename(client_msg); - SSH_LOG(SSH_LOG_PROTOCOL, "Processing setstat %s", filename); - if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); return SSH_ERROR; } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing setstat %s", filename); + if (msg_flags & SSH_FILEXFER_ATTR_SIZE) { rv = truncate(filename, client_msg->attr->size); if (rv < 0) { @@ -2195,13 +2221,14 @@ process_readlink(sftp_client_message client_msg) const char *sftp_err_msg = NULL; int status = SSH_FX_OK; - SSH_LOG(SSH_LOG_PROTOCOL, "Processing readlink %s", filename); - if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); return SSH_ERROR; } + SSH_LOG(SSH_LOG_PROTOCOL, "Processing readlink %s", filename); + len = readlink(filename, buf, sizeof(buf) - 1); if (len < 0) { int saved_errno = errno; @@ -2232,14 +2259,15 @@ process_symlink(sftp_client_message client_msg) int status = SSH_FX_OK; int rv; - SSH_LOG(SSH_LOG_PROTOCOL, "processing symlink: src=%s dest=%s", - srcpath, destpath); - if (srcpath == NULL || destpath == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); return SSH_ERROR; } + SSH_LOG(SSH_LOG_PROTOCOL, "processing symlink: src=%s dest=%s", + srcpath, destpath); + rv = symlink(srcpath, destpath); if (rv < 0) { int saved_errno = errno; @@ -2262,6 +2290,12 @@ process_remove(sftp_client_message client_msg) int rv; int status = SSH_FX_OK; + if (filename == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); + sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); + return SSH_ERROR; + } + SSH_LOG(SSH_LOG_PROTOCOL, "processing remove: %s", filename); rv = unlink(filename); @@ -2297,6 +2331,12 @@ process_extended_statvfs(sftp_client_message client_msg) int status; int rv; + if (path == NULL) { + SSH_LOG(SSH_LOG_WARNING, "missing filename from in message"); + sftp_reply_status(client_msg, SSH_FX_NO_SUCH_FILE, "File name error"); + return SSH_ERROR; + } + SSH_LOG(SSH_LOG_PROTOCOL, "processing extended statvfs: %s", path); rv = statvfs(path, &st);