diff -up fetchmail-6.3.6/report.c_old fetchmail-6.3.6/report.c --- fetchmail-6.3.6/report.c_old 2009-08-17 15:52:33.000000000 +0200 +++ fetchmail-6.3.6/report.c 2009-08-17 16:03:43.000000000 +0200 @@ -238,11 +238,17 @@ report_build (FILE *errfp, message, va_a rep_ensuresize(); #if defined(VA_START) - VA_START (args, message); for ( ; ; ) { + /* + * args has to be initialized before every call of vsnprintf(), + * because vsnprintf() invokes va_arg macro and thus args is + * undefined after the call. + */ + VA_START(args, message); n = vsnprintf (partial_message + partial_message_size_used, partial_message_size - partial_message_size_used, message, args); + va_end (args); if (n >= 0 && (unsigned)n < partial_message_size - partial_message_size_used) @@ -254,7 +260,6 @@ report_build (FILE *errfp, message, va_a partial_message_size += 2048; partial_message = REALLOC (partial_message, partial_message_size); } - va_end (args); #else for ( ; ; ) { @@ -304,12 +309,13 @@ report_complete (FILE *errfp, message, v rep_ensuresize(); #if defined(VA_START) - VA_START (args, message); for ( ; ; ) { + VA_START(args, message); n = vsnprintf (partial_message + partial_message_size_used, partial_message_size - partial_message_size_used, message, args); + va_end(args); /* old glibc versions return -1 for truncation */ if (n >= 0 @@ -322,7 +328,6 @@ report_complete (FILE *errfp, message, v partial_message_size += 2048; partial_message = REALLOC (partial_message, partial_message_size); } - va_end (args); #else for ( ; ; ) { diff -up fetchmail-6.3.6/sink.c_old fetchmail-6.3.6/sink.c --- fetchmail-6.3.6/sink.c_old 2009-08-17 15:47:05.000000000 +0200 +++ fetchmail-6.3.6/sink.c 2009-08-17 15:47:26.000000000 +0200 @@ -262,7 +262,7 @@ static int send_bouncemail(struct query const char *md1 = "MAILER-DAEMON", *md2 = "MAILER-DAEMON@"; /* don't bounce in reply to undeliverable bounces */ - if (!msg->return_path[0] || + if (!msg || !msg->return_path[0] || strcmp(msg->return_path, "<>") == 0 || strcasecmp(msg->return_path, md1) == 0 || strncasecmp(msg->return_path, md2, strlen(md2)) == 0) diff -up fetchmail-6.3.6/socket.c_old fetchmail-6.3.6/socket.c --- fetchmail-6.3.6/socket.c_old 2009-08-17 16:03:50.000000000 +0200 +++ fetchmail-6.3.6/socket.c 2009-08-17 16:13:22.000000000 +0200 @@ -681,6 +681,12 @@ static int SSL_verify_callback( int ok_r report(stderr, GT_("Bad certificate: Subject CommonName too long!\n")); return (0); } + if ((size_t)i > strlen(buf)) { + /* Name contains embedded NUL characters, so we complain. This is likely + * a certificate spoofing attack. */ + report(stderr, GT_("Bad certificate: Subject CommonName contains NUL, aborting!\n")); + return 0; + } if (_ssl_server_cname != NULL) { char *p1 = buf; char *p2 = _ssl_server_cname; @@ -692,12 +698,19 @@ static int SSL_verify_callback( int ok_r * first find a match among alternative names */ gens = X509_get_ext_d2i(x509_cert, NID_subject_alt_name, NULL, NULL); if (gens) { - int i, r; - for (i = 0, r = sk_GENERAL_NAME_num(gens); i < r; ++i) { - const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i); + int j, r; + for (j = 0, r = sk_GENERAL_NAME_num(gens); j < r; ++j) { + const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, j); if (gn->type == GEN_DNS) { char *p1 = (char *)gn->d.ia5->data; char *p2 = _ssl_server_cname; + /* Name contains embedded NUL characters, so we complain. This + * is likely a certificate spoofing attack. */ + if ((size_t)gn->d.ia5->length != strlen(p1)) { + report(stderr, GT_("Bad certificate: Subject Alternative Name contains NUL, aborting!\n")); + sk_GENERAL_NAME_free(gens); + return 0; + } if (outlevel >= O_VERBOSE) report(stderr, "Subject Alternative Name: %s\n", p1); if (*p1 == '*') {