]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: base64: check output boundaries within base64{dec,urldec}
authorDragan Dosen <ddosen@haproxy.com>
Tue, 24 Aug 2021 07:48:04 +0000 (09:48 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 24 Aug 2021 14:10:49 +0000 (16:10 +0200)
Ensure that no more than olen bytes is written to the output buffer,
otherwise we might experience an unexpected behavior.

While the original code used to validate that the output size was
always large enough before starting to write, this validation was
later broken by the commit below, allowing to 3-byte blocks to
areas whose size is not multiple of 3:

  commit ed697e4856e5ac0b9931fd50fd8ff1b7739e5d88
  Author: Emeric Brun <ebrun@haproxy.com>
  Date:   Mon Jan 14 14:38:39 2019 +0100

    BUG/MINOR: base64: dec func ignores padding for output size checking

    Decode function returns an error even if the ouptut buffer is
    large enought because the padding was not considered. This
    case was never met with current code base.

For base64urldec(), it's basically the same problem except that since
the input format supports arbitrary lengths, the problem has always
been there since its introduction in 2.4.

This should be backported to all stable branches having a backport of
the patch above (i.e. 2.0), with some adjustments depending on the
availability of the base64dec() and base64urldec().

src/base64.c

index 5c4ab3a47e8ba0d09cc3d3cc72027b17ba124d92..a01f0f6e8eb54820da9e88b1143e2d01e6f3d3d2 100644 (file)
@@ -167,9 +167,12 @@ int base64dec(const char *in, size_t ilen, char *out, size_t olen) {
                         */
 
                        /* xx000000 xx001111 xx111122 xx222222 */
-                       out[convlen]   = ((t[0] << 2) + (t[1] >> 4));
-                       out[convlen+1] = ((t[1] << 4) + (t[2] >> 2));
-                       out[convlen+2] = ((t[2] << 6) + (t[3] >> 0));
+                       if (convlen < olen)
+                               out[convlen]   = ((t[0] << 2) + (t[1] >> 4));
+                       if (convlen+1 < olen)
+                               out[convlen+1] = ((t[1] << 4) + (t[2] >> 2));
+                       if (convlen+2 < olen)
+                               out[convlen+2] = ((t[2] << 6) + (t[3] >> 0));
 
                        convlen += 3-pad;
 
@@ -237,9 +240,12 @@ int base64urldec(const char *in, size_t ilen, char *out, size_t olen)
                         */
 
                        /* xx000000 xx001111 xx111122 xx222222 */
-                       out[convlen]   = ((t[0] << 2) + (t[1] >> 4));
-                       out[convlen + 1] = ((t[1] << 4) + (t[2] >> 2));
-                       out[convlen + 2] = ((t[2] << 6) + (t[3] >> 0));
+                       if (convlen < olen)
+                               out[convlen]   = ((t[0] << 2) + (t[1] >> 4));
+                       if (convlen+1 < olen)
+                               out[convlen+1] = ((t[1] << 4) + (t[2] >> 2));
+                       if (convlen+2 < olen)
+                               out[convlen+2] = ((t[2] << 6) + (t[3] >> 0));
 
                        convlen += 3;
                        i = 0;