diff options
Diffstat (limited to 'meta-oe/recipes-dbs/postgresql/files/CVE-2021-23222.patch')
-rw-r--r-- | meta-oe/recipes-dbs/postgresql/files/CVE-2021-23222.patch | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/meta-oe/recipes-dbs/postgresql/files/CVE-2021-23222.patch b/meta-oe/recipes-dbs/postgresql/files/CVE-2021-23222.patch new file mode 100644 index 000000000..42b78539b --- /dev/null +++ b/meta-oe/recipes-dbs/postgresql/files/CVE-2021-23222.patch | |||
@@ -0,0 +1,131 @@ | |||
1 | From 79125ead2a6a234086844bb42f06d49603fe6ca0 Mon Sep 17 00:00:00 2001 | ||
2 | From: Tom Lane <tgl@sss.pgh.pa.us> | ||
3 | Date: Mon, 8 Nov 2021 11:14:56 -0500 | ||
4 | Subject: [PATCH 1/2] libpq: reject extraneous data after SSL or GSS encryption | ||
5 | handshake. | ||
6 | |||
7 | libpq collects up to a bufferload of data whenever it reads data from | ||
8 | the socket. When SSL or GSS encryption is requested during startup, | ||
9 | any additional data received with the server's yes-or-no reply | ||
10 | remained in the buffer, and would be treated as already-decrypted data | ||
11 | once the encryption handshake completed. Thus, a man-in-the-middle | ||
12 | with the ability to inject data into the TCP connection could stuff | ||
13 | some cleartext data into the start of a supposedly encryption-protected | ||
14 | database session. | ||
15 | |||
16 | This could probably be abused to inject faked responses to the | ||
17 | client's first few queries, although other details of libpq's behavior | ||
18 | make that harder than it sounds. A different line of attack is to | ||
19 | exfiltrate the client's password, or other sensitive data that might | ||
20 | be sent early in the session. That has been shown to be possible with | ||
21 | a server vulnerable to CVE-2021-23214. | ||
22 | |||
23 | To fix, throw a protocol-violation error if the internal buffer | ||
24 | is not empty after the encryption handshake. | ||
25 | |||
26 | Our thanks to Jacob Champion for reporting this problem. | ||
27 | |||
28 | Security: CVE-2021-23222 | ||
29 | |||
30 | Upstream-Status: Backport[https://github.com/postgres/postgres/commit/160c0258802d10b0600d7671b1bbea55d8e17d45] | ||
31 | CVE: CVE-2021-23222 | ||
32 | |||
33 | Signed-off-by: Changqing Li <changqing.li@windriver.com> | ||
34 | --- | ||
35 | doc/src/sgml/protocol.sgml | 28 ++++++++++++++++++++++++++++ | ||
36 | src/interfaces/libpq/fe-connect.c | 26 ++++++++++++++++++++++++++ | ||
37 | 2 files changed, 54 insertions(+) | ||
38 | |||
39 | diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml | ||
40 | index e26619e1b5..b692648fca 100644 | ||
41 | --- a/doc/src/sgml/protocol.sgml | ||
42 | +++ b/doc/src/sgml/protocol.sgml | ||
43 | @@ -1471,6 +1471,20 @@ SELCT 1/0;<!-- this typo is intentional --> | ||
44 | and proceed without requesting <acronym>SSL</acronym>. | ||
45 | </para> | ||
46 | |||
47 | + <para> | ||
48 | + When <acronym>SSL</acronym> encryption can be performed, the server | ||
49 | + is expected to send only the single <literal>S</literal> byte and then | ||
50 | + wait for the frontend to initiate an <acronym>SSL</acronym> handshake. | ||
51 | + If additional bytes are available to read at this point, it likely | ||
52 | + means that a man-in-the-middle is attempting to perform a | ||
53 | + buffer-stuffing attack | ||
54 | + (<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>). | ||
55 | + Frontends should be coded either to read exactly one byte from the | ||
56 | + socket before turning the socket over to their SSL library, or to | ||
57 | + treat it as a protocol violation if they find they have read additional | ||
58 | + bytes. | ||
59 | + </para> | ||
60 | + | ||
61 | <para> | ||
62 | An initial SSLRequest can also be used in a connection that is being | ||
63 | opened to send a CancelRequest message. | ||
64 | @@ -1532,6 +1546,20 @@ SELCT 1/0;<!-- this typo is intentional --> | ||
65 | encryption. | ||
66 | </para> | ||
67 | |||
68 | + <para> | ||
69 | + When <acronym>GSSAPI</acronym> encryption can be performed, the server | ||
70 | + is expected to send only the single <literal>G</literal> byte and then | ||
71 | + wait for the frontend to initiate a <acronym>GSSAPI</acronym> handshake. | ||
72 | + If additional bytes are available to read at this point, it likely | ||
73 | + means that a man-in-the-middle is attempting to perform a | ||
74 | + buffer-stuffing attack | ||
75 | + (<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>). | ||
76 | + Frontends should be coded either to read exactly one byte from the | ||
77 | + socket before turning the socket over to their GSSAPI library, or to | ||
78 | + treat it as a protocol violation if they find they have read additional | ||
79 | + bytes. | ||
80 | + </para> | ||
81 | + | ||
82 | <para> | ||
83 | An initial GSSENCRequest can also be used in a connection that is being | ||
84 | opened to send a CancelRequest message. | ||
85 | diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c | ||
86 | index f80f4e98d8..57aee95183 100644 | ||
87 | --- a/src/interfaces/libpq/fe-connect.c | ||
88 | +++ b/src/interfaces/libpq/fe-connect.c | ||
89 | @@ -3076,6 +3076,19 @@ keep_going: /* We will come back to here until there is | ||
90 | pollres = pqsecure_open_client(conn); | ||
91 | if (pollres == PGRES_POLLING_OK) | ||
92 | { | ||
93 | + /* | ||
94 | + * At this point we should have no data already buffered. | ||
95 | + * If we do, it was received before we performed the SSL | ||
96 | + * handshake, so it wasn't encrypted and indeed may have | ||
97 | + * been injected by a man-in-the-middle. | ||
98 | + */ | ||
99 | + if (conn->inCursor != conn->inEnd) | ||
100 | + { | ||
101 | + appendPQExpBufferStr(&conn->errorMessage, | ||
102 | + libpq_gettext("received unencrypted data after SSL response\n")); | ||
103 | + goto error_return; | ||
104 | + } | ||
105 | + | ||
106 | /* SSL handshake done, ready to send startup packet */ | ||
107 | conn->status = CONNECTION_MADE; | ||
108 | return PGRES_POLLING_WRITING; | ||
109 | @@ -3175,6 +3188,19 @@ keep_going: /* We will come back to here until there is | ||
110 | pollres = pqsecure_open_gss(conn); | ||
111 | if (pollres == PGRES_POLLING_OK) | ||
112 | { | ||
113 | + /* | ||
114 | + * At this point we should have no data already buffered. | ||
115 | + * If we do, it was received before we performed the GSS | ||
116 | + * handshake, so it wasn't encrypted and indeed may have | ||
117 | + * been injected by a man-in-the-middle. | ||
118 | + */ | ||
119 | + if (conn->inCursor != conn->inEnd) | ||
120 | + { | ||
121 | + appendPQExpBufferStr(&conn->errorMessage, | ||
122 | + libpq_gettext("received unencrypted data after GSSAPI encryption response\n")); | ||
123 | + goto error_return; | ||
124 | + } | ||
125 | + | ||
126 | /* All set for startup packet */ | ||
127 | conn->status = CONNECTION_MADE; | ||
128 | return PGRES_POLLING_WRITING; | ||
129 | -- | ||
130 | 2.17.1 | ||
131 | |||