From 9e8a1af632b7fe5df1d9b3098f2863dcbd5acd00 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sun, 10 Sep 2017 00:00:00 -0500 Subject: [PATCH] postfix-3.3-20170910 --- postfix/HISTORY | 36 +++++++++++++++++++++++++++- postfix/src/global/mail_version.h | 2 +- postfix/src/postqueue/showq_compat.c | 2 +- postfix/src/util/vbuf_print.c | 19 +++++++++++---- postfix/src/util/vbuf_print_test.in | 7 ++++++ postfix/src/util/vbuf_print_test.ref | 6 +++++ postfix/src/util/vstream.c | 2 ++ postfix/src/util/vstring.c | 2 +- 8 files changed, 68 insertions(+), 8 deletions(-) diff --git a/postfix/HISTORY b/postfix/HISTORY index 432d6980b..7df544a65 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -23057,7 +23057,7 @@ Apologies for any names omitted. Typos (introduced: Postfix 2.10): in comments about IPv4-in-IPv6 addresses, replace :ffff::1.2.3.4 with the - correct form :ffff::1.2.3.4. Incorrect or misleading comments + correct form ::ffff:1.2.3.4. Incorrect or misleading comments are worse than no comments. Files: smtpd/smtpd_haproxy.c, postscreen/postscreen_haproxy.c. @@ -23117,3 +23117,37 @@ Apologies for any names omitted. to always store the verify result under the original address, and to conditionally store it under the rewritten address. File: global/verify.c. + +20170827 + + Safety: in vstream_buf_space(), add a sanity check to reject + negative request sizes, instead of letting the program fail + later. File: util/vstream.c + + Bugfix: in tests that enable the VSTRING_FLAG_EXACT flag, + vstring_buf_put_ready() could fail to extend the buffer, + causing infinite recursion in VBUF_PUT(). File: util/vstring.c. + +20170830 + + Bugfix: in vbuf_print(), save the parser-produced format + string before calling msg_panic(), so that the panic message + will not display its own format string. File: util/vbuf_print.c. + +20170831 + + Portability (introduced Postfix 1.0): possible cause for + panic in postqueue when listing the deferred queue. This + assigned the result from unsigned integer subtraction to a + signed integer, followed by a safety check to ensure that + the result was non-negative. This assignment relied on + undefined behavior, meaning that a compiler may eliminate + the safety check, causing the program to fail later. File: + postqueue/showq_compat.c. + +20170910 + + Safety: restore sanity checks for dynamically-specified + width and precision in format strings (%*, %.*, and %*.*). + These checks were lost with the Postfix 3.2.2 rewrite of + the vbuf_print formatter. File: vbuf_print.c. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 9e45f2ea8..b61fa6e36 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20170730" +#define MAIL_RELEASE_DATE "20170910" #define MAIL_VERSION_NUMBER "3.3" #ifdef SNAPSHOT diff --git a/postfix/src/postqueue/showq_compat.c b/postfix/src/postqueue/showq_compat.c index c533288e8..7899b1eef 100644 --- a/postfix/src/postqueue/showq_compat.c +++ b/postfix/src/postqueue/showq_compat.c @@ -154,7 +154,7 @@ static unsigned long showq_message(VSTREAM *showq_stream) myfree(saved_reason); saved_reason = mystrdup(STR(why)); show_reason = *saved_reason ? saved_reason : "reason unavailable"; - if ((padding = 76 - strlen(show_reason)) < 0) + if ((padding = 76 - (int) strlen(show_reason)) < 0) padding = 0; vstream_printf("%*s(%s)\n", padding, "", show_reason); } diff --git a/postfix/src/util/vbuf_print.c b/postfix/src/util/vbuf_print.c index 63718ad62..5e63ee9f4 100644 --- a/postfix/src/util/vbuf_print.c +++ b/postfix/src/util/vbuf_print.c @@ -64,6 +64,7 @@ /* Application-specific. */ #include "msg.h" +#include "mymalloc.h" #include "vbuf.h" #include "vstring.h" #include "vbuf_print.h" @@ -109,10 +110,10 @@ VBUF_SPACE((bp), (sz)); \ _ret = snprintf((char *) (bp)->ptr, (bp)->cnt, (fmt), (arg)); \ if (_ret < 0) \ - msg_panic("%s: output error for '%s'", myname, (fmt)); \ + msg_panic("%s: output error for '%s'", myname, mystrdup(fmt)); \ if (_ret >= (bp)->cnt) \ msg_panic("%s: output for '%s' exceeds space %ld", \ - myname, fmt, (long) (bp)->cnt); \ + myname, mystrdup(fmt), (long) (bp)->cnt); \ VBUF_SKIP(bp); \ } while (0) #else @@ -192,7 +193,12 @@ VBUF *vbuf_print(VBUF *bp, const char *format, va_list ap) VSTRING_ADDCH(fmt, *cp++); if (*cp == '*') { /* dynamic field width */ width = va_arg(ap, int); - VSTRING_ADDNUM(fmt, width); + if (width < 0) { + msg_warn("%s: bad width %d in %.50s", + myname, width, format); + width = 0; + } else + VSTRING_ADDNUM(fmt, width); cp++; } else { /* hard-coded field width */ for (width = 0; ch = *cp, ISDIGIT(ch); cp++) { @@ -210,7 +216,12 @@ VBUF *vbuf_print(VBUF *bp, const char *format, va_list ap) VSTRING_ADDCH(fmt, *cp++); if (*cp == '*') { /* dynamic precision */ prec = va_arg(ap, int); - VSTRING_ADDNUM(fmt, prec); + if (prec < 0) { + msg_warn("%s: bad precision %d in %.50s", + myname, prec, format); + prec = -1; + } else + VSTRING_ADDNUM(fmt, prec); cp++; } else { /* hard-coded precision */ for (prec = 0; ch = *cp, ISDIGIT(ch); cp++) { diff --git a/postfix/src/util/vbuf_print_test.in b/postfix/src/util/vbuf_print_test.in index 655b4a5c0..5ed13dc1f 100644 --- a/postfix/src/util/vbuf_print_test.in +++ b/postfix/src/util/vbuf_print_test.in @@ -24,3 +24,10 @@ %.100f 1e308 %g 1e308 %.309g 1e308 + +%s foo +%0s foo +%.0s foo +%10s foo +%+10s foo +%-10s foo diff --git a/postfix/src/util/vbuf_print_test.ref b/postfix/src/util/vbuf_print_test.ref index 40abbafbf..346c91991 100644 --- a/postfix/src/util/vbuf_print_test.ref +++ b/postfix/src/util/vbuf_print_test.ref @@ -19,3 +19,9 @@ ./vbuf_print: "100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ./vbuf_print: "1e+308" ./vbuf_print: "100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336" +./vbuf_print: "foo" +./vbuf_print: "foo" +./vbuf_print: "" +./vbuf_print: " foo" +./vbuf_print: " foo" +./vbuf_print: "foo " diff --git a/postfix/src/util/vstream.c b/postfix/src/util/vstream.c index 00c066c43..9afcd55f7 100644 --- a/postfix/src/util/vstream.c +++ b/postfix/src/util/vstream.c @@ -980,6 +980,8 @@ static int vstream_buf_space(VBUF *bp, ssize_t want) */ if (bp->put_ready == 0) msg_panic("%s: read-only stream", myname); + if (want < 0) + msg_panic("%s: bad length %ld", myname, (long) want); switch (bp->flags & (VSTREAM_FLAG_READ | VSTREAM_FLAG_WRITE)) { case VSTREAM_FLAG_READ: /* change direction */ bp->flags &= ~VSTREAM_FLAG_READ; diff --git a/postfix/src/util/vstring.c b/postfix/src/util/vstring.c index c13767279..fa1586e3e 100644 --- a/postfix/src/util/vstring.c +++ b/postfix/src/util/vstring.c @@ -331,7 +331,7 @@ static int vstring_buf_get_ready(VBUF *unused_buf) static int vstring_buf_put_ready(VBUF *bp) { - vstring_extend(bp, 0); + vstring_extend(bp, 1); return (0); }