]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
pgsql: parse auth message within its bound
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 17 Oct 2023 20:01:27 +0000 (22:01 +0200)
committerVictor Julien <vjulien@oisf.net>
Tue, 6 Feb 2024 14:59:20 +0000 (15:59 +0100)
If the next PDU is already in the slice next, do not use it and
restrict ourselves to the length of this PDU.
Avoids overconsumption of memory by quadratic complexity, when
having many small PDUS in one big chunk being parsed

Ticket: #6411
(cherry picked from commit f52c033e566beafb4480c139eb18662a2870464f)

rust/src/pgsql/parser.rs

index 97a16b57384fbb2e41d8be7a8bba7c1e7d1b6733..3fd3f8546f1df6bbde5db2797ef98ec0169f0156 100644 (file)
@@ -719,7 +719,6 @@ fn pgsql_parse_authentication_message<'a>(i: &'a [u8]) -> IResult<&'a [u8], Pgsq
     let (i, identifier) = verify(be_u8, |&x| x == b'R')(i)?;
     let (i, length) = verify(be_u32, |&x| x >= 8)(i)?;
     let (i, auth_type) = be_u32(i)?;
-    let (i, payload) = peek(rest)(i)?;
     let (i, message) = map_parser(
         take(length - 8),
         |b: &'a [u8]| {
@@ -729,14 +728,14 @@ fn pgsql_parse_authentication_message<'a>(i: &'a [u8]) -> IResult<&'a [u8], Pgsq
                                 identifier,
                                 length,
                                 auth_type,
-                                payload: payload.to_vec(),
+                                payload: b.to_vec(),
                             }))),
                 3 => Ok((b, PgsqlBEMessage::AuthenticationCleartextPassword(
                             AuthenticationMessage {
                                 identifier,
                                 length,
                                 auth_type,
-                                payload: payload.to_vec(),
+                                payload: b.to_vec(),
                             }))),
                 5 => {
                     let (b, salt) = all_consuming(take(4_usize))(b)?;
@@ -753,7 +752,7 @@ fn pgsql_parse_authentication_message<'a>(i: &'a [u8]) -> IResult<&'a [u8], Pgsq
                                 identifier,
                                 length,
                                 auth_type,
-                                payload: payload.to_vec(),
+                                payload: b.to_vec(),
                             }))),
                 // TODO - For SASL, should we parse specific details of the challenge itself? (as seen in: https://github.com/launchbadge/sqlx/blob/master/sqlx-core/src/postgres/message/authentication.rs )
                 10 => {
@@ -767,23 +766,21 @@ fn pgsql_parse_authentication_message<'a>(i: &'a [u8]) -> IResult<&'a [u8], Pgsq
                                 })))
                 }
                 11 => {
-                    let (b, sasl_challenge) = rest(i)?;
                     Ok((b, PgsqlBEMessage::AuthenticationSASLContinue(
                                 AuthenticationMessage {
                                     identifier,
                                     length,
                                     auth_type,
-                                    payload: sasl_challenge.to_vec(),
+                                    payload: b.to_vec(),
                                 })))
                 },
                 12 => {
-                    let (i, signature) = take(length - 8)(i)?;
-                    Ok((i, PgsqlBEMessage::AuthenticationSASLFinal(
+                    Ok((b, PgsqlBEMessage::AuthenticationSASLFinal(
                                 AuthenticationMessage {
                                     identifier,
                                     length,
                                     auth_type,
-                                    payload: signature.to_vec(),
+                                    payload: b.to_vec(),
                                 }
                                 )))
                 }