Skip to content

Commit

Permalink
Additonal safeguard : Prefer the use of unsigned pointer sizes for re…
Browse files Browse the repository at this point in the history
…prensenting length in core functions instead of signed int in order to prevent possibly existing overflows for crafted requests.

This should also fix buffer overflows in the case someone run that software on a 16 bit x86 with an already supported ᴏꜱ.
  • Loading branch information
ytrezq committed May 30, 2016
1 parent 5739711 commit ca033a3
Show file tree
Hide file tree
Showing 88 changed files with 428 additions and 399 deletions.
6 changes: 3 additions & 3 deletions doc/doc-docbook/spec.xfpt
Original file line number Diff line number Diff line change
Expand Up @@ -32407,15 +32407,15 @@ match the specification, the function does nothing.


.vitem "&*BOOL&~header_testname(header_line&~*hdr,&~uschar&~*name,&~&&&
int&~length,&~BOOL&~notdel)*&"
size_t&~length,&~BOOL&~notdel)*&"
This function tests whether the given header has the given name. It is not just
a string comparison, because white space is permitted between the name and the
colon. If the &%notdel%& argument is true, a false return is forced for all
&"deleted"& headers; otherwise they are not treated specially. For example:
.code
if (header_testname(h, US"X-Spam", 6, TRUE)) ...
.endd
.vitem &*uschar&~*lss_b64encode(uschar&~*cleartext,&~int&~length)*&
.vitem &*uschar&~*lss_b64encode(uschar&~*cleartext,&~size_t&~length)*&
.cindex "base64 encoding" "functions for &[local_scan()]& use"
This function base64-encodes a string, which is passed by address and length.
The text may contain bytes of any value, including zero. The result is passed
Expand Down Expand Up @@ -32505,7 +32505,7 @@ address.
.cindex "RFC 2047"
.vlist
.vitem "&*uschar&~rfc2047_decode(uschar&~*string,&~BOOL&~lencheck,&&&
&~uschar&~*target,&~int&~zeroval,&~int&~*lenptr, &~&~uschar&~**error)*&"
&~uschar&~*target,&~int&~zeroval,&~size_t&~*lenptr, &~&~uschar&~**error)*&"
This function decodes strings that are encoded according to RFC 2047. Typically
these are the contents of header lines. First, each &"encoded word"& is decoded
from the Q or B encoding into a byte-string. Then, if provided with the name of
Expand Down
8 changes: 8 additions & 0 deletions doc/doc-txt/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ JH/07 Retire gnutls_require_mac et.al. These were nonfunctional since 4.80
JH/08 Bug 1836: Fix crash in VRFY handling when handed an unqualified name
(lacking @domain). Apply the same qualification processing as RCPT.

LC/01 Prefer the use of size_t for variables representing sizes. Even if most
strings in Exim are limited to 2¹⁵, This acts as a suplemental protection
against overflows.
Especially for 16 bits x86 where INT_MAX is already 2¹⁵ and pointers used in
Unix programs are FAR (20 bits wide).
In the meantime, this doesn’t impact any cases where negative length could have
been used, as an error value.


Exim version 4.87
-----------------
Expand Down
2 changes: 1 addition & 1 deletion src/exim_monitor/em_TextPop.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ struct SearchAndReplace * search;
text.firstPos = 0;
text.format = FMT8BIT;

dir = (XawTextScanDirection)(int) ((caddr_t)XawToggleGetCurrent(search->left_toggle) -
dir = (XawTextScanDirection)(size_t) ((caddr_t)XawToggleGetCurrent(search->left_toggle) -
R_OFFSET);

pos = XawTextSearch( tw, dir, &text);
Expand Down
2 changes: 1 addition & 1 deletion src/exim_monitor/em_hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ typedef struct queue_item {
struct dest_item *destinations;
int input_time;
int update_time;
int size;
size_t size;
uschar *sender;
uschar name[17];
uschar seen;
Expand Down
2 changes: 1 addition & 1 deletion src/exim_monitor/em_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ while (p != NULL)

for (skp = &queue_skip; ; skp = &(sk->next))
{
int len_skip;
size_t len_skip;

sk = *skp;
while (sk != NULL && now >= sk->reveal)
Expand Down
2 changes: 1 addition & 1 deletion src/exim_monitor/em_strip.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static void stripchartAction(Widget w, XtPointer client_data, XtPointer value)
double *ptr = (double *)value;
static int thresholds[] =
{10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 0};
int num = (int)client_data;
size_t num = (size_t)client_data;
int oldmax = 0;
int newmax = 0;
int newvalue = 0;
Expand Down
12 changes: 6 additions & 6 deletions src/src/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ static void
setup_header(const uschar *hstring)
{
const uschar *p, *q;
int hlen = Ustrlen(hstring);
size_t hlen = Ustrlen(hstring);

/* Ignore any leading newlines */
while (*hstring == '\n') hstring++, hlen--;
Expand Down Expand Up @@ -1159,8 +1159,8 @@ uschar *
fn_hdrs_added(void)
{
uschar * ret = NULL;
int size = 0;
int ptr = 0;
size_t size = 0;
size_t ptr = 0;
header_line * h = acl_added_headers;
uschar * s;
uschar * cp;
Expand Down Expand Up @@ -1259,7 +1259,7 @@ if (log_message != NULL && log_message != user_message)

if (logged == NULL)
{
int length = Ustrlen(text) + 1;
size_t length = Ustrlen(text) + 1;
log_write(0, LOG_MAIN, "%s", text);
logged = store_malloc(sizeof(string_item) + length);
logged->text = (uschar *)logged + sizeof(string_item);
Expand Down Expand Up @@ -1651,7 +1651,7 @@ typedef struct {
int value;
unsigned where_allowed; /* bitmap */
BOOL no_options; /* Never has /option(s) following */
unsigned alt_opt_sep; /* >0 Non-/ option separator (custom parser) */
size_t alt_opt_sep; /* >0 Non-/ option separator (custom parser) */
} verify_type_t;
static verify_type_t verify_type_list[] = {
{ US"reverse_host_lookup", VERIFY_REV_HOST_LKUP, ~0, FALSE, 0 },
Expand Down Expand Up @@ -2340,7 +2340,7 @@ int mode = RATE_PER_WHAT;
int old_pool, rc;
tree_node **anchor, *t;
open_db dbblock, *dbm;
int dbdb_size;
size_t dbdb_size;
dbdata_ratelimit *dbd;
dbdata_ratelimit_unique *dbdb;
struct timeval tv;
Expand Down
2 changes: 1 addition & 1 deletion src/src/auths/check_serv_cond.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ HDEBUG(D_auth)
debug_printf(" $auth%d = %s\n", i + 1, auth_vars[i]);
}
for (i = 1; i <= expand_nmax; i++)
debug_printf(" $%d = %.*s\n", i, expand_nlength[i], expand_nstring[i]);
debug_printf(" $%u = %.*s\n", i, (unsigned int)expand_nlength[i], expand_nstring[i]);
debug_print_string(ablock->server_debug_string); /* customized debug */
}

Expand Down
4 changes: 2 additions & 2 deletions src/src/auths/cram_md5.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ compute_cram_md5(uschar *secret, uschar *challenge, uschar *digestptr)
{
md5 base;
int i;
int len = Ustrlen(secret);
size_t len = Ustrlen(secret);
uschar isecret[64];
uschar osecret[64];
uschar md5secret[16];
Expand Down Expand Up @@ -250,7 +250,7 @@ auth_cram_md5_client(
smtp_outblock *outblock, /* output connection */
int timeout, /* command timeout */
uschar *buffer, /* for reading response */
int buffsize) /* size of buffer */
size_t buffsize) /* size of buffer */
{
auth_cram_md5_options_block *ob =
(auth_cram_md5_options_block *)(ablock->options_block);
Expand Down
2 changes: 1 addition & 1 deletion src/src/auths/cram_md5.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ extern auth_cram_md5_options_block auth_cram_md5_option_defaults;
extern void auth_cram_md5_init(auth_instance *);
extern int auth_cram_md5_server(auth_instance *, uschar *);
extern int auth_cram_md5_client(auth_instance *, smtp_inblock *,
smtp_outblock *, int, uschar *, int);
smtp_outblock *, int, uschar *, size_t);

/* End of cram_md5.h */
2 changes: 1 addition & 1 deletion src/src/auths/heimdal_gssapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ auth_heimdal_gssapi_server(auth_instance *ablock, uschar *initial_data)

expand_nlength[1] = gbufdesc_out.length;
auth_vars[0] = expand_nstring[1] =
string_copyn(gbufdesc_out.value, gbufdesc_out.length);
string_copyn(gbufdesc_out.value, (size_t)gbufdesc_out.length);

if (expand_nmax == 0) { /* should be: authzid was empty */
expand_nmax = 2;
Expand Down
6 changes: 4 additions & 2 deletions src/src/auths/plaintext.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ auth_plaintext_client(
smtp_outblock *outblock, /* connection outblock */
int timeout, /* command timeout */
uschar *buffer, /* buffer for reading response */
int buffsize) /* size of buffer */
size_t buffsize) /* size of buffer */
{
auth_plaintext_options_block *ob =
(auth_plaintext_options_block *)(ablock->options_block);
Expand All @@ -175,7 +175,9 @@ sent in response to subsequent prompts. Each is expanded before being sent. */

while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)) != NULL)
{
int i, len, clear_len;
int i;
ssize_t clear_len;
size_t len;
uschar *ss = expand_string(s);
uschar *clear;

Expand Down
2 changes: 1 addition & 1 deletion src/src/auths/plaintext.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ extern auth_plaintext_options_block auth_plaintext_option_defaults;
extern void auth_plaintext_init(auth_instance *);
extern int auth_plaintext_server(auth_instance *, uschar *);
extern int auth_plaintext_client(auth_instance *, smtp_inblock *,
smtp_outblock *, int, uschar *, int);
smtp_outblock *, int, uschar *, size_t);

/* End of plaintext.h */
2 changes: 1 addition & 1 deletion src/src/auths/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ auth_spa_client(
smtp_outblock *outblock, /* connection outblock */
int timeout, /* command timeout */
uschar *buffer, /* buffer for reading response */
int buffsize) /* size of buffer */
size_t buffsize) /* size of buffer */
{
auth_spa_options_block *ob =
(auth_spa_options_block *)(ablock->options_block);
Expand Down
2 changes: 1 addition & 1 deletion src/src/auths/spa.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ extern auth_spa_options_block auth_spa_option_defaults;
extern void auth_spa_init(auth_instance *);
extern int auth_spa_server(auth_instance *, uschar *);
extern int auth_spa_client(auth_instance *, smtp_inblock *,
smtp_outblock *, int, uschar *, int);
smtp_outblock *, int, uschar *, size_t);

/* End of spa.h */
2 changes: 1 addition & 1 deletion src/src/auths/xtextencode.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ uschar *code;
uschar *p = (uschar *)clear;
uschar *pp;
int c = len;
int count = 1;
size_t count = 1;
register int x;

/* We have to do a prepass to find out how many specials there are,
Expand Down
2 changes: 1 addition & 1 deletion src/src/base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ static uschar *enc64table =
US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

uschar *
b64encode(uschar *clear, int len)
b64encode(uschar *clear, size_t len)
{
uschar *code = store_get(4*((len+2)/3) + 1);
uschar *p = code;
Expand Down
16 changes: 8 additions & 8 deletions src/src/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ union sockaddr_46 interface_sockaddr;
EXIM_SOCKLEN_T ifsize = sizeof(interface_sockaddr);
int dup_accept_socket = -1;
int max_for_this_host = 0;
int wfsize = 0;
int wfptr = 0;
size_t wfsize = 0;
size_t wfptr = 0;
int save_log_selector = *log_selector;
uschar *whofrom = NULL;

Expand Down Expand Up @@ -1065,10 +1065,10 @@ if (daemon_listen && !inetd_wait_mode)
{
uschar *new_smtp_port = NULL;
uschar *new_local_interfaces = NULL;
int portsize = 0;
int portptr = 0;
int ifacesize = 0;
int ifaceptr = 0;
size_t portsize = 0;
size_t portptr = 0;
size_t ifacesize = 0;
size_t ifaceptr = 0;

if (override_pid_file_path == NULL) write_pid = FALSE;

Expand All @@ -1078,8 +1078,8 @@ if (daemon_listen && !inetd_wait_mode)
{
uschar joinstr[4];
uschar **ptr;
int *sizeptr;
int *ptrptr;
size_t *sizeptr;
size_t *ptrptr;

if (Ustrpbrk(s, ".:") == NULL)
{
Expand Down
10 changes: 5 additions & 5 deletions src/src/dbfn.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ Returns: a pointer to the retrieved record, or
*/

void *
dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
dbfn_read_with_length(open_db *dbblock, const uschar *key, size_t *length)
{
void *yield;
EXIM_DATUM key_datum, result_datum;
int klen = Ustrlen(key) + 1;
size_t klen = Ustrlen(key) + 1;
uschar * key_copy = store_get(klen);

memcpy(key_copy, key, klen);
Expand Down Expand Up @@ -338,11 +338,11 @@ Returns: the yield of the underlying dbm or db "write" function. If this
*/

int
dbfn_write(open_db *dbblock, const uschar *key, void *ptr, int length)
dbfn_write(open_db *dbblock, const uschar *key, void *ptr, size_t length)
{
EXIM_DATUM key_datum, value_datum;
dbdata_generic *gptr = (dbdata_generic *)ptr;
int klen = Ustrlen(key) + 1;
size_t klen = Ustrlen(key) + 1;
uschar * key_copy = store_get(klen);

memcpy(key_copy, key, klen);
Expand Down Expand Up @@ -376,7 +376,7 @@ Returns: the yield of the underlying dbm or db "delete" function.
int
dbfn_delete(open_db *dbblock, const uschar *key)
{
int klen = Ustrlen(key) + 1;
size_t klen = Ustrlen(key) + 1;
uschar * key_copy = store_get(klen);

memcpy(key_copy, key, klen);
Expand Down
4 changes: 2 additions & 2 deletions src/src/dbfunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
void dbfn_close(open_db *);
int dbfn_delete(open_db *, const uschar *);
open_db *dbfn_open(uschar *, int, open_db *, BOOL);
void *dbfn_read_with_length(open_db *, const uschar *, int *);
void *dbfn_read_with_length(open_db *, const uschar *, size_t *);
uschar *dbfn_scan(open_db *, BOOL, EXIM_CURSOR **);
int dbfn_write(open_db *, const uschar *, void *, int);
int dbfn_write(open_db *, const uschar *, void *, size_t);

/* Macro for the common call to read without wanting to know the length. */

Expand Down
Loading

0 comments on commit ca033a3

Please sign in to comment.