diff options
Diffstat (limited to 'debian/patches/84_22-CVE-2020-28019-Failure-to-reset-function-pointer-aft.patch')
-rw-r--r-- | debian/patches/84_22-CVE-2020-28019-Failure-to-reset-function-pointer-aft.patch | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/debian/patches/84_22-CVE-2020-28019-Failure-to-reset-function-pointer-aft.patch b/debian/patches/84_22-CVE-2020-28019-Failure-to-reset-function-pointer-aft.patch new file mode 100644 index 0000000..0d44293 --- /dev/null +++ b/debian/patches/84_22-CVE-2020-28019-Failure-to-reset-function-pointer-aft.patch @@ -0,0 +1,135 @@ +From 1663ab541b37675dec5bcf235605568ff36ac65a Mon Sep 17 00:00:00 2001 +From: Qualys Security Advisory <qsa@qualys.com> +Date: Sun, 21 Feb 2021 22:36:10 -0800 +Subject: [PATCH 22/29] CVE-2020-28019: Failure to reset function pointer after + BDAT error + +Based on Phil Pennock's commits 4715403e and 151ffd72, and Jeremy +Harris's commits aa171254 and 9aceb5c2. +--- + src/globals.c | 1 + + src/globals.h | 1 + + src/smtp_in.c | 55 +++++++++++++++++++++++++++++++++++++++-------- + 3 files changed, 48 insertions(+), 9 deletions(-) + +diff --git a/src/globals.c b/src/globals.c +index b3362a34c..894b8487b 100644 +--- a/src/globals.c ++++ b/src/globals.c +@@ -247,6 +247,7 @@ struct global_flags f = + .authentication_local = FALSE, + + .background_daemon = TRUE, ++ .bdat_readers_wanted = FALSE, + + .chunking_offered = FALSE, + .config_changed = FALSE, +diff --git a/src/globals.h b/src/globals.h +index f71f104e2..58f7ae55f 100644 +--- a/src/globals.h ++++ b/src/globals.h +@@ -173,6 +173,7 @@ extern struct global_flags { + BOOL authentication_local :1; /* TRUE if non-smtp (implicit authentication) */ + + BOOL background_daemon :1; /* Set FALSE to keep in foreground */ ++ BOOL bdat_readers_wanted :1; /* BDAT-handling to be pushed on readfunc stack */ + + BOOL chunking_offered :1; + BOOL config_changed :1; /* True if -C used */ +diff --git a/src/smtp_in.c b/src/smtp_in.c +index 1a5fbfea3..016c44c0f 100644 +--- a/src/smtp_in.c ++++ b/src/smtp_in.c +@@ -602,6 +602,10 @@ if (n > 0) + #endif + } + ++/* Forward declarations */ ++static inline void bdat_push_receive_functions(void); ++static inline void bdat_pop_receive_functions(void); ++ + + /* Get a byte from the smtp input, in CHUNKING mode. Handle ack of the + previous BDAT chunk and getting new ones when we run out. Uses the +@@ -634,9 +638,7 @@ for(;;) + if (chunking_data_left > 0) + return lwr_receive_getc(chunking_data_left--); + +- receive_getc = lwr_receive_getc; +- receive_getbuf = lwr_receive_getbuf; +- receive_ungetc = lwr_receive_ungetc; ++ bdat_pop_receive_functions(); + #ifndef DISABLE_DKIM + dkim_save = dkim_collect_input; + dkim_collect_input = 0; +@@ -740,9 +742,7 @@ next_cmd: + goto repeat_until_rset; + } + +- receive_getc = bdat_getc; +- receive_getbuf = bdat_getbuf; /* r~getbuf is never actually used */ +- receive_ungetc = bdat_ungetc; ++ bdat_push_receive_functions(); + #ifndef DISABLE_DKIM + dkim_collect_input = dkim_save; + #endif +@@ -775,9 +775,7 @@ while (chunking_data_left) + if (!bdat_getbuf(&n)) break; + } + +-receive_getc = lwr_receive_getc; +-receive_getbuf = lwr_receive_getbuf; +-receive_ungetc = lwr_receive_ungetc; ++bdat_pop_receive_functions(); + + if (chunking_state != CHUNKING_LAST) + { +@@ -787,6 +785,45 @@ if (chunking_state != CHUNKING_LAST) + } + + ++static inline void ++bdat_push_receive_functions(void) ++{ ++/* push the current receive_* function on the "stack", and ++replace them by bdat_getc(), which in turn will use the lwr_receive_* ++functions to do the dirty work. */ ++if (lwr_receive_getc == NULL) ++ { ++ lwr_receive_getc = receive_getc; ++ lwr_receive_getbuf = receive_getbuf; ++ lwr_receive_ungetc = receive_ungetc; ++ } ++else ++ { ++ DEBUG(D_receive) debug_printf("chunking double-push receive functions\n"); ++ } ++ ++receive_getc = bdat_getc; ++receive_getbuf = bdat_getbuf; ++receive_ungetc = bdat_ungetc; ++} ++ ++static inline void ++bdat_pop_receive_functions(void) ++{ ++if (lwr_receive_getc == NULL) ++ { ++ DEBUG(D_receive) debug_printf("chunking double-pop receive functions\n"); ++ return; ++ } ++ ++receive_getc = lwr_receive_getc; ++receive_getbuf = lwr_receive_getbuf; ++receive_ungetc = lwr_receive_ungetc; ++ ++lwr_receive_getc = NULL; ++lwr_receive_getbuf = NULL; ++lwr_receive_ungetc = NULL; ++} + + + /************************************************* +-- +2.30.2 + |