Gitweb:
https://git.exim.org/exim.git/commitdiff/62a4137ec452ff0a6801923930b003e954ec09aa
Commit: 62a4137ec452ff0a6801923930b003e954ec09aa
Parent: 996a98d33f790a1e6af927c02318649feec6061b
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Thu Dec 31 22:18:30 2020 +0000
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Thu Dec 31 22:18:30 2020 +0000
malware: avoid slurping entire spoolfile for sending to ClamAV
---
src/src/malware.c | 61 +++++++++++++++++++++++--------------------------------
1 file changed, 25 insertions(+), 36 deletions(-)
diff --git a/src/src/malware.c b/src/src/malware.c
index 03bb832..2883f22 100644
--- a/src/src/malware.c
+++ b/src/src/malware.c
@@ -1445,7 +1445,6 @@ badseek: err = errno;
host_item connhost;
uschar *clamav_fbuf;
int clam_fd, result;
- off_t fsize;
unsigned int fsize_uint;
BOOL use_scan_command = FALSE;
clamd_address * cv[MAX_CLAMD_SERVERS];
@@ -1621,6 +1620,7 @@ badseek: err = errno;
if (!use_scan_command)
{
+ struct stat st;
/* New protocol: "zINSTREAM\n" followed by a sequence of <length><data>
chunks, <n> a 4-byte number (network order), terminated by a zero-length
chunk. */
@@ -1637,7 +1637,6 @@ badseek: err = errno;
strerror(errno)),
malware_daemon_ctx.sock);
- /* calc file size */
if ((clam_fd = exim_open2(CS eml_filename, O_RDONLY)) < 0)
{
int err = errno;
@@ -1646,61 +1645,51 @@ badseek: err = errno;
eml_filename, strerror(err)),
malware_daemon_ctx.sock);
}
- if ((fsize = lseek(clam_fd, 0, SEEK_END)) < 0)
+ if (fstat(clam_fd, &st) < 0)
{
- int err;
-b_seek: err = errno;
+ int err = errno;
(void)close(clam_fd);
return m_panic_defer_3(scanent, NULL,
- string_sprintf("can't seek spool file %s: %s",
+ string_sprintf("can't stat spool file %s: %s",
eml_filename, strerror(err)),
malware_daemon_ctx.sock);
}
- fsize_uint = (unsigned int) fsize;
- if ((off_t)fsize_uint != fsize)
+ fsize_uint = (unsigned int) st.st_size;
+ if ((off_t)fsize_uint != st.st_size)
{
(void)close(clam_fd);
return m_panic_defer_3(scanent, NULL,
- string_sprintf("seeking spool file %s, size overflow",
- eml_filename),
+ string_sprintf("stat spool file %s, size overflow", eml_filename),
malware_daemon_ctx.sock);
}
- if (lseek(clam_fd, 0, SEEK_SET) < 0)
- goto b_seek;
- if (!(clamav_fbuf = store_malloc(fsize_uint)))
- {
- (void)close(clam_fd);
+ /* send file body to socket */
+ send_size = htonl(fsize_uint);
+ if (send(malware_daemon_ctx.sock, &send_size, sizeof(send_size), 0) < 0)
return m_panic_defer_3(scanent, NULL,
- string_sprintf("unable to allocate memory %u for file (%s)",
- fsize_uint, eml_filename),
+ string_sprintf("unable to send file size to socket (%s)", hostname),
malware_daemon_ctx.sock);
- }
- if ((result = read(clam_fd, clamav_fbuf, fsize_uint)) < 0)
+ while (fsize_uint)
{
- int err = errno;
- store_free(clamav_fbuf); (void)close(clam_fd);
- return m_panic_defer_3(scanent, NULL,
- string_sprintf("can't read spool file %s: %s",
- eml_filename, strerror(err)),
- malware_daemon_ctx.sock);
+ unsigned n = MIN(fsize_uint, big_buffer_size);
+ if ((n = read(clam_fd, big_buffer, n)) < 0)
+ return m_panic_defer_3(scanent, NULL,
+ string_sprintf("can't read spool file %s: %s",
+ eml_filename, strerror(errno)),
+ malware_daemon_ctx.sock);
+ if ((n = send(malware_daemon_ctx.sock, clamav_fbuf, n, 0)) < 0)
+ return m_panic_defer_3(scanent, NULL,
+ string_sprintf("unable to send file body to socket (%s)", hostname),
+ malware_daemon_ctx.sock);
+ fsize_uint -= n;
}
- (void)close(clam_fd);
- /* send file body to socket */
- send_size = htonl(fsize_uint);
send_final_zeroblock = 0;
- if ((send(malware_daemon_ctx.sock, &send_size, sizeof(send_size), 0) < 0) ||
- (send(malware_daemon_ctx.sock, clamav_fbuf, fsize_uint, 0) < 0) ||
- (send(malware_daemon_ctx.sock, &send_final_zeroblock, sizeof(send_final_zeroblock), 0) < 0))
- {
- store_free(clamav_fbuf);
+ if (send(malware_daemon_ctx.sock, &send_final_zeroblock, sizeof(send_final_zeroblock), 0) < 0)
return m_panic_defer_3(scanent, NULL,
- string_sprintf("unable to send file body to socket (%s)", hostname),
+ string_sprintf("unable to send file terminator to socket (%s)", hostname),
malware_daemon_ctx.sock);
- }
- store_free(clamav_fbuf);
}
else
{ /* use scan command */