From d2b8ad5f07dcafbede1fcc00a269b70ca1cb496f Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 14 Jan 2026 13:31:57 -0800 Subject: [PATCH] tftp: use lseek() for file size determination and handle errors Replace fstat() with lseek(SEEK_END) for determining file size when the tsize option is requested. This approach is more portable and doesn't require struct stat. Additionally, handle the case where lseek() fails (e.g., on unseekable files like pipes or special devices). When this occurs, send a TFTP ERROR with code 0 (Not defined) and a descriptive message to inform the client that the file size cannot be determined. After obtaining the size, reset the file position to the beginning with lseek(SEEK_SET) to ensure subsequent reads start from the correct offset. Also fix resource leak: close the socket when file open fails, ensuring proper cleanup in all error paths. Signed-off-by: Bjorn Andersson --- tqftpserv.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tqftpserv.c b/tqftpserv.c index d4435ce..a88929f 100644 --- a/tqftpserv.c +++ b/tqftpserv.c @@ -357,7 +357,6 @@ static void handle_rrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) struct tftp_client *client; const char *filename; const char *mode; - struct stat sb; const char *p; const char *end = buf + len; size_t filename_len, mode_len; @@ -437,8 +436,16 @@ static void handle_rrq(const char *buf, size_t len, struct sockaddr_qrtr *sq) } if (tsize != -1) { - fstat(fd, &sb); - tsize = sb.st_size; + tsize = lseek(fd, 0, SEEK_END); + if (tsize < 0) { + printf("[TQFTP] unable to determine file size for %s: %s\n", + filename, strerror(errno)); + tftp_send_error(sock, TFTP_ERROR_UNDEF, "Cannot determine file size"); + goto out_close_sock; + return; + } + /* Reset file position to beginning */ + lseek(fd, 0, SEEK_SET); } client = calloc(1, sizeof(*client));