git://git.exim.org
/
users
/
jgh
/
exim.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
2b058a9
)
Check "socket" scanner commandline spec for no more than one %s expansion
author
Jeremy Harris
<jgh146exb@wizmail.org>
Sun, 16 Feb 2014 18:09:40 +0000
(18:09 +0000)
committer
Jeremy Harris
<jgh146exb@wizmail.org>
Sun, 16 Feb 2014 18:09:40 +0000
(18:09 +0000)
src/src/malware.c
patch
|
blob
|
history
diff --git
a/src/src/malware.c
b/src/src/malware.c
index 298031aa39a2777905cbcdec9fdca5c5696499c6..93e30c06f1b3b78e4d2ea790c2370eb2010e640f 100644
(file)
--- a/
src/src/malware.c
+++ b/
src/src/malware.c
@@
-154,7
+154,7
@@
malware_errlog(const uschar * str)
{
log_write(0, LOG_MAIN|LOG_PANIC, "malware acl condition: %s", str);
}
{
log_write(0, LOG_MAIN|LOG_PANIC, "malware acl condition: %s", str);
}
-static int
+static in
line in
t
malware_errlog_defer(const uschar * str)
{
malware_errlog(str);
malware_errlog_defer(const uschar * str)
{
malware_errlog(str);
@@
-269,7
+269,8
@@
m_unixsocket(const uschar * path, uschar ** errstr)
}
server.sun_family = AF_UNIX;
}
server.sun_family = AF_UNIX;
- Ustrcpy(server.sun_path, path);
+ Ustrncpy(server.sun_path, path, sizeof(server.sun_path)-1);
+ server.sun_path[sizeof(server.sun_path)-1] = '\0';
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
int err = errno;
(void)close(sock);
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
int err = errno;
(void)close(sock);
@@
-1531,18
+1532,26
@@
malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
by David Saez and the cmdline code
*/
{
by David Saez and the cmdline code
*/
{
- int sock, bread
=0
;
+ int sock, bread;
uschar * commandline;
uschar av_buffer[1024];
uschar * linebuffer;
uschar * commandline;
uschar av_buffer[1024];
uschar * linebuffer;
- uschar *sockline_scanner;
+ uschar *
sockline_scanner;
uschar sockline_scanner_default[] = "%s\n";
const pcre *sockline_trig_re;
const pcre *sockline_name_re;
uschar sockline_scanner_default[] = "%s\n";
const pcre *sockline_trig_re;
const pcre *sockline_name_re;
+ int err;
/* find scanner command line */
/* find scanner command line */
- if (
!
(sockline_scanner = string_nextinlist(&av_scanner_work, &sep,
+ if ((sockline_scanner = string_nextinlist(&av_scanner_work, &sep,
NULL, 0)))
NULL, 0)))
+ { /* check for no expansions apart from one %s */
+ char * s = index(sockline_scanner, '%');
+ if (s++)
+ if (*s != 's' && *s != '%' || index(s+1, '%'))
+ return sock_errlog_defer("unsafe sock scanner call spec");
+ }
+ else
sockline_scanner = sockline_scanner_default;
/* find scanner output trigger */
sockline_scanner = sockline_scanner_default;
/* find scanner output trigger */
@@
-1557,7
+1566,7
@@
malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
if (!sockline_name_re)
return sock_errlog_defer(errstr);
if (!sockline_name_re)
return sock_errlog_defer(errstr);
- /* prepare scanner call */
+ /* prepare scanner call
- security depends on expansions check above
*/
commandline = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, message_id);
commandline = string_sprintf( CS sockline_scanner, CS commandline);
commandline = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, message_id);
commandline = string_sprintf( CS sockline_scanner, CS commandline);
@@
-1573,17
+1582,15
@@
malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
if (m_sock_send(sock, commandline, Ustrlen(commandline), &errstr) < 0)
return sock_errlog_defer(errstr);
if (m_sock_send(sock, commandline, Ustrlen(commandline), &errstr) < 0)
return sock_errlog_defer(errstr);
- /* We're done sending, close socket for writing. */
- /* shutdown(sock, SHUT_WR); */
-
/* Read the result */
memset(av_buffer, 0, sizeof(av_buffer));
bread = read(sock, av_buffer, sizeof(av_buffer));
/* Read the result */
memset(av_buffer, 0, sizeof(av_buffer));
bread = read(sock, av_buffer, sizeof(av_buffer));
+ err = errno;
(void)close(sock);
if (!(bread > 0))
return sock_errlog_defer(
(void)close(sock);
if (!(bread > 0))
return sock_errlog_defer(
- string_sprintf("unable to read from socket (%s)", strerror(err
no
)));
+ string_sprintf("unable to read from socket (%s)", strerror(err)));
if (bread == sizeof(av_buffer))
return sock_errlog_defer("buffer too small");
if (bread == sizeof(av_buffer))
return sock_errlog_defer("buffer too small");