From 8300a7b40dbdf00739f90a0b0c30066ff9224fd9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 17 Jan 2023 16:09:30 -0500 Subject: [PATCH] Upgrade sendfile7 to not mash size on stack. offset is a nullptr most of the time, don't dereference it. When falling back to read/write, just read in chunks of 4096, because I don't know how to make llvm use c99 dynamic arrays. Check for HAVE_SENDFILE. Fixes #3505 --- src/zm_sendfile.h | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/zm_sendfile.h b/src/zm_sendfile.h index d30dc1460..aa5225b3c 100644 --- a/src/zm_sendfile.h +++ b/src/zm_sendfile.h @@ -1,46 +1,57 @@ #ifndef ZM_SENDFILE_H #define ZM_SENDFILE_H -#ifdef HAVE_SENDFILE4_SUPPORT +#if defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE4_SUPPORT) #include -#elif HAVE_SENDFILE7_SUPPORT +#elif defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE7_SUPPORT) #include #include #include #else #include +#include #endif /* Function to send the contents of a file. Will use sendfile or fall back to reading/writing */ -ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, ssize_t size) { -#ifdef HAVE_SENDFILE4_SUPPORT +ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { +#if defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE4_SUPPORT) ssize_t err = sendfile(out_fd, in_fd, offset, size); if (err < 0) { return -errno; } return err; -#elif HAVE_SENDFILE7_SUPPORT - off_t sbytes = 0; - off_t ofs = offset ? *offset : 0; - ssize_t err = sendfile(in_fd, out_fd, ofs, size, nullptr, &sbytes, 0); +#elif defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE7_SUPPORT) + off_t sbytes; + ssize_t err = sendfile(in_fd, out_fd, (offset ? *offset: 0), size, nullptr, &sbytes, 0); if (err && errno != EAGAIN) return -errno; return sbytes; #else - uint8_t buffer[size]; - ssize_t err = read(in_fd, buffer, size); + uint8_t buffer[4096]; + size_t chunk_size = (size > 4096 ? 4096 : size); + + ssize_t err = read(in_fd, buffer, chunk_size); if (err < 0) { - Error("Unable to read %zu bytes: %s", size, strerror(errno)); + Error("Unable to read %zu bytes of %zu: %s", chunk_size, size, strerror(errno)); return -errno; } + if (!err) { + Error("Got EOF despite wanting to read %zu bytes", 4096); + return err; + } - err = write(out_fd, buffer, size); + chunk_size = err; + + err = write(out_fd, buffer, chunk_size); if (err < 0) { - Error("Unable to write %zu bytes: %s", size, strerror(errno)); + Error("Unable to write %zu bytes: %s", chunk_size, strerror(errno)); return -errno; + } else if (err != chunk_size) { + Debug(1, "Sent less than desired %zu < %zu", err, chunk_size); } + return err; #endif }