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 <bjorn.andersson@oss.qualcomm.com>
This commit is contained in:
Bjorn Andersson
2026-01-14 13:31:57 -08:00
committed by Bjorn Andersson
parent dd4eebcf5e
commit d2b8ad5f07

View File

@@ -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));