]> git.pld-linux.org Git - packages/exim.git/blame - unofficial-hotfix.patch
Rel 25; unofficial hotfix for some of recent SECURITY issues (timelime for official...
[packages/exim.git] / unofficial-hotfix.patch
CommitLineData
05c80ef3
AM
1Date: Sun, 1 Oct 2023 11:33:26 +0200\r
2To: exim-dev@lists.exim.org\r
3From: Florian Zumbiehl via Exim-dev <exim-dev@lists.exim.org>\r
4\r
5Hi,\r
6\r
7below you find a patch that fixes some (probably three?) of what I guess are\r
8the vulnerabilities reported by ZDI.\r
9\r
10Please note that the patch is only mildly tested, it is developed based on\r
11the git master branch, but can be applied to older versions with minor\r
12massaging. If you go back far enough, proxy.c was part of smtp_in.c, but if\r
13you adjust for that, the patch can be made to apply there, too.\r
14\r
15Obviously, I have no idea whether this actually addresses what ZDI has\r
16reported, but if not, these probably should be fixed, too, and if so, given\r
17the fact that I managed to rather easily find these vulnerabilities based\r
18on the information that's publicly available, I don't think there is much\r
19point to trying to keep this secret any longer--if anything, it's\r
20counterproductive.\r
21\r
22Also mind you that this is a hot fix, it's neither elegant, nor does it do\r
23any useful error reporting, the goal was simply to prevent out of bounds\r
24accesses.\r
25\r
26Florian\r
27\r
28---\r
29\r
30diff --git a/src/src/auths/external.c b/src/src/auths/external.c\r
31index 078aad0..54966e6 100644\r
32--- a/src/src/auths/external.c\r
33+++ b/src/src/auths/external.c\r
34@@ -101,6 +101,9 @@ if (expand_nmax == 0) /* skip if rxd data */\r
35 if ((rc = auth_prompt(CUS"")) != OK)\r
36 return rc;\r
37 \r
38+if (expand_nmax != 1)\r
39+ return FAIL;\r
40+\r
41 if (ob->server_param2)\r
42 {\r
43 uschar * s = expand_string(ob->server_param2);\r
44diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c\r
45index 222ccea..66967d6 100644\r
46--- a/src/src/auths/spa.c\r
47+++ b/src/src/auths/spa.c\r
48@@ -166,12 +166,18 @@ if (auth_get_no64_data(&data, msgbuf) != OK)\r
49 return FAIL;\r
50 \r
51 /* dump client response */\r
52-if (spa_base64_to_bits(CS &response, sizeof(response), CCS data) < 0)\r
53+int l = spa_base64_to_bits(CS &response, sizeof(response), CCS data);\r
54+if (l < 0)\r
55 {\r
56 DEBUG(D_auth) debug_printf("auth_spa_server(): bad base64 data in "\r
57 "response: %s\n", data);\r
58 return FAIL;\r
59 }\r
60+if(l < (char *)&response.buffer - (char *)&response)return FAIL;\r
61+unsigned long o = IVAL(&response.uUser.offset, 0);\r
62+if((l < o) || (l - o < SVAL(&response.uUser.len, 0)))return FAIL;\r
63+o = IVAL(&response.ntResponse.offset, 0);\r
64+if((l < o) || (l - o < 24))return FAIL;\r
65 \r
66 /***************************************************************\r
67 PH 07-Aug-2003: The original code here was this:\r
68@@ -346,7 +352,10 @@ if (!smtp_read_response(sx, US buffer, buffsize, '3', timeout))\r
69 \r
70 /* convert the challenge into the challenge struct */\r
71 DSPA("\n\n%s authenticator: challenge (%s)\n\n", ablock->name, buffer + 4);\r
72-spa_base64_to_bits(CS (&challenge), sizeof(challenge), CCS (buffer + 4));\r
73+int l = spa_base64_to_bits(CS (&challenge), sizeof(challenge), CCS (buffer + 4));\r
74+if((l < 0) || (l < (char *)&challenge.buffer - (char *)&challenge))return FAIL;\r
75+unsigned long o = IVAL(&challenge.uDomain.offset, 0);\r
76+if((l < o) || (l - o < SVAL(&challenge.uDomain.len, 0)))return FAIL;\r
77 \r
78 spa_build_auth_response(&challenge, &response, CS username, CS password);\r
79 spa_bits_to_base64(US msgbuf, US &response, spa_request_length(&response));\r
80diff --git a/src/src/proxy.c b/src/src/proxy.c\r
81index fbce111..8dd7034 100644\r
82--- a/src/src/proxy.c\r
83+++ b/src/src/proxy.c\r
84@@ -93,6 +93,8 @@ while (capacity > 0)\r
85 do { ret = read(fd, to, 1); } while (ret == -1 && errno == EINTR && !had_command_timeout);\r
86 if (ret == -1)\r
87 return -1;\r
88+ if (!ret)\r
89+ break;\r
90 have++;\r
91 if (last)\r
92 return have;\r
93@@ -254,6 +256,8 @@ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0))\r
94 goto proxyfail;\r
95 }\r
96 \r
97+ if (ret < 16)\r
98+ goto proxyfail;\r
99 /* The v2 header will always be 16 bytes per the spec. */\r
100 size = 16 + ntohs(hdr.v2.len);\r
101 DEBUG(D_receive) debug_printf("Detected PROXYv2 header, size %d (limit %d)\n",\r
102@@ -274,7 +278,7 @@ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0))\r
103 {\r
104 retmore = read(fd, (uschar*)&hdr + ret, size-ret);\r
105 } while (retmore == -1 && errno == EINTR && !had_command_timeout);\r
106- if (retmore == -1)\r
107+ if (retmore < 1)\r
108 goto proxyfail;\r
109 DEBUG(D_receive) proxy_debug(US &hdr, ret, ret + retmore);\r
110 ret += retmore;\r
111@@ -297,6 +301,8 @@ if (ret >= 16 && memcmp(&hdr.v2, v2sig, 12) == 0)\r
112 switch (hdr.v2.fam)\r
113 {\r
114 case 0x11: /* TCPv4 address type */\r
115+ if (ret < 28)\r
116+ goto proxyfail;\r
117 iptype = US"IPv4";\r
118 tmpaddr.sin_addr.s_addr = hdr.v2.addr.ip4.src_addr;\r
119 inet_ntop(AF_INET, &tmpaddr.sin_addr, CS &tmpip, sizeof(tmpip));\r
120@@ -323,6 +329,8 @@ if (ret >= 16 && memcmp(&hdr.v2, v2sig, 12) == 0)\r
121 proxy_external_port = tmpport;\r
122 goto done;\r
123 case 0x21: /* TCPv6 address type */\r
124+ if (ret < 52)\r
125+ goto proxyfail;\r
126 iptype = US"IPv6";\r
127 memmove(tmpaddr6.sin6_addr.s6_addr, hdr.v2.addr.ip6.src_addr, 16);\r
128 inet_ntop(AF_INET6, &tmpaddr6.sin6_addr, CS &tmpip6, sizeof(tmpip6));\r
129@@ -381,10 +389,13 @@ else if (ret >= 8 && memcmp(hdr.v1.line, "PROXY", 5) == 0)\r
130 goto proxyfail;\r
131 ret += r2;\r
132 \r
133+ if(ret > 107)\r
134+ goto proxyfail;\r
135+ hdr.v1.line[ret] = 0;\r
136 p = string_copy(hdr.v1.line);\r
137 end = memchr(p, '\r', ret - 1);\r
138 \r
139- if (!end || (end == (uschar*)&hdr + ret) || end[1] != '\n')\r
140+ if (!end || end[1] != '\n')\r
141 {\r
142 DEBUG(D_receive) debug_printf("Partial or invalid PROXY header\n");\r
143 goto proxyfail;\r
144\r
145-- \r
146## subscription configuration (requires account):\r
147## https://lists.exim.org/mailman3/postorius/lists/exim-dev.lists.exim.org/\r
148## unsubscribe (doesn't require an account):\r
149## exim-dev-unsubscribe@lists.exim.org\r
150## Exim details at http://www.exim.org/\r
151## Please use the Wiki with this list - http://wiki.exim.org/\r
This page took 0.091925 seconds and 4 git commands to generate.