Merge branch 'debian'
[hcoop/debian/exim4.git] / debian / patches / 84_22-CVE-2020-28019-Failure-to-reset-function-pointer-aft.patch
CommitLineData
0c0c20aa
AM
1From 1663ab541b37675dec5bcf235605568ff36ac65a Mon Sep 17 00:00:00 2001
2From: Qualys Security Advisory <qsa@qualys.com>
3Date: Sun, 21 Feb 2021 22:36:10 -0800
4Subject: [PATCH 22/29] CVE-2020-28019: Failure to reset function pointer after
5 BDAT error
6
7Based on Phil Pennock's commits 4715403e and 151ffd72, and Jeremy
8Harris's commits aa171254 and 9aceb5c2.
9---
10 src/globals.c | 1 +
11 src/globals.h | 1 +
12 src/smtp_in.c | 55 +++++++++++++++++++++++++++++++++++++++--------
13 3 files changed, 48 insertions(+), 9 deletions(-)
14
15diff --git a/src/globals.c b/src/globals.c
16index b3362a34c..894b8487b 100644
17--- a/src/globals.c
18+++ b/src/globals.c
19@@ -247,6 +247,7 @@ struct global_flags f =
20 .authentication_local = FALSE,
21
22 .background_daemon = TRUE,
23+ .bdat_readers_wanted = FALSE,
24
25 .chunking_offered = FALSE,
26 .config_changed = FALSE,
27diff --git a/src/globals.h b/src/globals.h
28index f71f104e2..58f7ae55f 100644
29--- a/src/globals.h
30+++ b/src/globals.h
31@@ -173,6 +173,7 @@ extern struct global_flags {
32 BOOL authentication_local :1; /* TRUE if non-smtp (implicit authentication) */
33
34 BOOL background_daemon :1; /* Set FALSE to keep in foreground */
35+ BOOL bdat_readers_wanted :1; /* BDAT-handling to be pushed on readfunc stack */
36
37 BOOL chunking_offered :1;
38 BOOL config_changed :1; /* True if -C used */
39diff --git a/src/smtp_in.c b/src/smtp_in.c
40index 1a5fbfea3..016c44c0f 100644
41--- a/src/smtp_in.c
42+++ b/src/smtp_in.c
43@@ -602,6 +602,10 @@ if (n > 0)
44 #endif
45 }
46
47+/* Forward declarations */
48+static inline void bdat_push_receive_functions(void);
49+static inline void bdat_pop_receive_functions(void);
50+
51
52 /* Get a byte from the smtp input, in CHUNKING mode. Handle ack of the
53 previous BDAT chunk and getting new ones when we run out. Uses the
54@@ -634,9 +638,7 @@ for(;;)
55 if (chunking_data_left > 0)
56 return lwr_receive_getc(chunking_data_left--);
57
58- receive_getc = lwr_receive_getc;
59- receive_getbuf = lwr_receive_getbuf;
60- receive_ungetc = lwr_receive_ungetc;
61+ bdat_pop_receive_functions();
62 #ifndef DISABLE_DKIM
63 dkim_save = dkim_collect_input;
64 dkim_collect_input = 0;
65@@ -740,9 +742,7 @@ next_cmd:
66 goto repeat_until_rset;
67 }
68
69- receive_getc = bdat_getc;
70- receive_getbuf = bdat_getbuf; /* r~getbuf is never actually used */
71- receive_ungetc = bdat_ungetc;
72+ bdat_push_receive_functions();
73 #ifndef DISABLE_DKIM
74 dkim_collect_input = dkim_save;
75 #endif
76@@ -775,9 +775,7 @@ while (chunking_data_left)
77 if (!bdat_getbuf(&n)) break;
78 }
79
80-receive_getc = lwr_receive_getc;
81-receive_getbuf = lwr_receive_getbuf;
82-receive_ungetc = lwr_receive_ungetc;
83+bdat_pop_receive_functions();
84
85 if (chunking_state != CHUNKING_LAST)
86 {
87@@ -787,6 +785,45 @@ if (chunking_state != CHUNKING_LAST)
88 }
89
90
91+static inline void
92+bdat_push_receive_functions(void)
93+{
94+/* push the current receive_* function on the "stack", and
95+replace them by bdat_getc(), which in turn will use the lwr_receive_*
96+functions to do the dirty work. */
97+if (lwr_receive_getc == NULL)
98+ {
99+ lwr_receive_getc = receive_getc;
100+ lwr_receive_getbuf = receive_getbuf;
101+ lwr_receive_ungetc = receive_ungetc;
102+ }
103+else
104+ {
105+ DEBUG(D_receive) debug_printf("chunking double-push receive functions\n");
106+ }
107+
108+receive_getc = bdat_getc;
109+receive_getbuf = bdat_getbuf;
110+receive_ungetc = bdat_ungetc;
111+}
112+
113+static inline void
114+bdat_pop_receive_functions(void)
115+{
116+if (lwr_receive_getc == NULL)
117+ {
118+ DEBUG(D_receive) debug_printf("chunking double-pop receive functions\n");
119+ return;
120+ }
121+
122+receive_getc = lwr_receive_getc;
123+receive_getbuf = lwr_receive_getbuf;
124+receive_ungetc = lwr_receive_ungetc;
125+
126+lwr_receive_getc = NULL;
127+lwr_receive_getbuf = NULL;
128+lwr_receive_ungetc = NULL;
129+}
130
131
132 /*************************************************
133--
1342.30.2
135