From 7390e768d82239b8dc6697379277c37c8c927b9d Mon Sep 17 00:00:00 2001 From: Phil Pennock Date: Fri, 18 May 2012 15:46:06 -0400 Subject: [PATCH] Fix dcc_header content corruption. (stack memory referenced, read-only, out of scope). Patch from Wolfgang Breyha, report from Stuart Northfield. --- doc/doc-txt/ChangeLog | 4 ++++ src/src/EDITME | 5 +++++ src/src/dcc.c | 40 +++++++++++++++++++--------------------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index b3815cd45..2c0646b54 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -118,6 +118,10 @@ PP/27 Applied dnsdb SPF support patch from Janne Snabb. JH/04 Added expansion variable $tod_epoch_l for a higher-precision time. +PP/28 Fix DCC dcc_header content corruption (stack memory referenced, + read-only, out of scope). + Patch from Wolfgang Breyha, report from Stuart Northfield. + Exim version 4.77 ----------------- diff --git a/src/src/EDITME b/src/src/EDITME index 1f717a988..941a42e7a 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -416,6 +416,11 @@ EXIM_MONITOR=eximon.bin # experimental-spec.txt. "Experimental" means that the way these features are # implemented may still change. Backward compatibility is not guaranteed. +# Uncomment the following line to add support for talking to dccifd. This +# defaults the socket path to /usr/local/dcc/var/dccifd. + +# EXPERIMENTAL_DCC=yes + # Uncomment the following lines to add SPF support. You need to have libspf2 # installed on your system (www.libspf2.org). Depending on where it is installed # you may have to edit the CFLAGS and LDFLAGS lines. diff --git a/src/src/dcc.c b/src/src/dcc.c index 2ad451d0b..20bd75afa 100644 --- a/src/src/dcc.c +++ b/src/src/dcc.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Wolfgang Breyha 2005-2009 +/* Copyright (c) Wolfgang Breyha 2005-2012 * Vienna University Computer Center * wbreyha@gmx.net * See the file NOTICE for conditions of use and distribution. @@ -19,7 +19,6 @@ #include "unistd.h" uschar dcc_header_str[256]; -uschar dcc_result_str[256]; int dcc_ok = 0; int dcc_rc = 0; @@ -68,7 +67,6 @@ int dcc_process(uschar **listptr) { uschar rcpt[128], from[128]; uschar sendbuf[4096]; uschar recvbuf[4096]; - uschar xhdr[256]; uschar dcc_return_text[1024]; uschar mbox_path[1024]; uschar message_subdir[2]; @@ -173,7 +171,7 @@ int dcc_process(uschar **listptr) { retval = DEFER; bzero(sendbuf,sizeof(sendbuf)); - bzero(xhdr,sizeof(xhdr)); + bzero(dcc_header_str,sizeof(dcc_header_str)); bzero(rcpt,sizeof(rcpt)); bzero(from,sizeof(from)); @@ -302,7 +300,7 @@ int dcc_process(uschar **listptr) { } } - /* a blank line separates header from body */ + /* a blank line seperates header from body */ Ustrncat(sendbuf, "\n", sizeof(sendbuf)-Ustrlen(sendbuf)-1); flushbuffer(sockfd, sendbuf); DEBUG(D_acl) @@ -353,7 +351,7 @@ int dcc_process(uschar **listptr) { line = 1; /* we start at the first line of the output */ j = 0; /* will be used as index for the recipients list */ - k = 0; /* initializing the index of the X-DCC header: xhdr[k] */ + k = 0; /* initializing the index of the X-DCC header: dcc_header_str[k] */ /* Let's read from the socket until there's nothing left to read */ bzero(recvbuf, sizeof(recvbuf)); @@ -441,16 +439,16 @@ int dcc_process(uschar **listptr) { } else if(line == 2) { /* On the second line we get a list of - * answer for each recipient. We don't care about - * it because we're in an acl and so just take the + * answers for each recipient. We don't care about + * it because we're in an acl and take the * global result. */ } else if(line > 2) { - /* The third and following lines is the X-DCC header, - * so we store it in xhdr. */ - /* check if we don't get more than what we can handle */ - if(k < sizeof(xhdr)) { /* xhdr has a length of 120 */ - xhdr[k] = recvbuf[i]; + /* The third and following lines are the X-DCC header, + * so we store it in dcc_header_str. */ + /* check if we don't get more than we can handle */ + if(k < sizeof(dcc_header_str)) { + dcc_header_str[k] = recvbuf[i]; k++; } else { @@ -470,26 +468,26 @@ int dcc_process(uschar **listptr) { } /* We have read everything from the socket */ - /* We need the terminate the X-DCC header with a '\n' character. This needs to be k-1 - * for xhdr[k] contains '\0'. */ - xhdr[k-1] = '\n'; + /* We need to terminate the X-DCC header with a '\n' character. This needs to be k-1 + * since dcc_header_str[k] contains '\0'. */ + dcc_header_str[k-1] = '\n'; /* Now let's sum up what we've got. */ DEBUG(D_acl) - debug_printf("\n--------------------------\nOverall result = %d\nX-DCC header: %sReturn message: %s\ndcc_result: %s\n", retval, xhdr, dcc_return_text, dcc_result); + debug_printf("\n--------------------------\nOverall result = %d\nX-DCC header: %sReturn message: %s\ndcc_result: %s\n", retval, dcc_header_str, dcc_return_text, dcc_result); /* We only add the X-DCC header if it starts with X-DCC */ - if(!(Ustrncmp(xhdr, "X-DCC", 5))){ - dcc_header = xhdr; + if(!(Ustrncmp(dcc_header_str, "X-DCC", 5))){ + dcc_header = dcc_header_str; if(dcc_direct_add_header) { - header_add(' ' , "%s", xhdr); + header_add(' ' , "%s", dcc_header_str); /* since the MIME ACL already writes the .eml file to disk without DCC Header we've to erase it */ unspool_mbox(); } } else { DEBUG(D_acl) - debug_printf("Wrong format of the X-DCC header: %s\n", xhdr); + debug_printf("Wrong format of the X-DCC header: %s\n", dcc_header_str); } /* check if we should add additional headers passed in acl_m_dcc_add_header */ -- 2.25.1