File security-advisory-8-stack-overflow-in-parser.patch of Package socat.37644
commit 226c555edb82f6901d7d7448d93e6d09b1132c73
Author: Gerhard Rieger <gerhard@dest-unreach.org>
Date: Tue Jan 26 19:08:18 2016 +0100
socat security advisory 8: stack overflow in nestlex()
diff --git a/nestlex.c b/nestlex.c
index 97778bc..f4a8962 100644
--- a/nestlex.c
+++ b/nestlex.c
@@ -1,5 +1,5 @@
/* source: nestlex.c */
-/* Copyright Gerhard Rieger 2006-2010 */
+/* Copyright Gerhard Rieger */
/* Published under the GNU General Public License V.2, see file COPYING */
/* a function for lexical scanning of nested character patterns */
@@ -9,6 +9,17 @@
#include "sysincludes.h"
+static int _nestlex(const char **addr,
+ char **token,
+ ptrdiff_t *len,
+ const char *ends[],
+ const char *hquotes[],
+ const char *squotes[],
+ const char *nests[],
+ bool dropquotes,
+ bool c_esc,
+ bool html_esc
+ );
/* sub: scan a string and copy its value to output string
end scanning when an unescaped, unnested string from ends array is found
@@ -33,6 +44,22 @@ int nestlex(const char **addr, /* input string; aft points to end token */
bool c_esc, /* solve C char escapes: \n \t \0 etc */
bool html_esc /* solve HTML char escapes: %0d %08 etc */
) {
+ return
+ _nestlex(addr, token, (ptrdiff_t *)len, ends, hquotes, squotes, nests,
+ dropquotes, c_esc, html_esc);
+}
+
+static int _nestlex(const char **addr,
+ char **token,
+ ptrdiff_t *len,
+ const char *ends[],
+ const char *hquotes[],
+ const char *squotes[],
+ const char *nests[],
+ bool dropquotes,
+ bool c_esc,
+ bool html_esc
+ ) {
const char *in = *addr; /* pointer into input string */
const char **endx; /* loops over end patterns */
const char **quotx; /* loops over quote patterns */
@@ -77,16 +104,18 @@ int nestlex(const char **addr, /* input string; aft points to end token */
if (--*len <= 0) { *addr = in; *token = out; return -1; }
}
}
- /* we call nestlex recursively */
+ /* we call _nestlex recursively */
endnest[0] = *quotx;
endnest[1] = NULL;
result =
- nestlex(&in, &out, len, endnest, NULL/*hquotes*/,
+ _nestlex(&in, &out, len, endnest, NULL/*hquotes*/,
NULL/*squotes*/, NULL/*nests*/,
false, c_esc, html_esc);
if (result == 0 && dropquotes) {
/* we strip this quote */
in += strlen(*quotx);
+ } else if (result < 0) {
+ *addr = in; *token = out; return result;
} else {
/* we copy the trailing quote */
for (i = strlen(*quotx); i > 0; --i) {
@@ -110,7 +139,7 @@ int nestlex(const char **addr, /* input string; aft points to end token */
if (!strncmp(in, *quotx, strlen(*quotx))) {
/* this quote pattern matches */
/* we strip this quote */
- /* we call nestlex recursively */
+ /* we call _nestlex recursively */
const char *endnest[2];
if (dropquotes) {
/* we strip this quote */
@@ -124,13 +153,15 @@ int nestlex(const char **addr, /* input string; aft points to end token */
endnest[0] = *quotx;
endnest[1] = NULL;
result =
- nestlex(&in, &out, len, endnest, hquotes,
+ _nestlex(&in, &out, len, endnest, hquotes,
squotes, nests,
false, c_esc, html_esc);
if (result == 0 && dropquotes) {
/* we strip the trailing quote */
in += strlen(*quotx);
+ } else if (result < 0) {
+ *addr = in; *token = out; return result;
} else {
/* we copy the trailing quote */
for (i = strlen(*quotx); i > 0; --i) {
@@ -162,7 +193,7 @@ int nestlex(const char **addr, /* input string; aft points to end token */
}
result =
- nestlex(&in, &out, len, endnest, hquotes, squotes, nests,
+ _nestlex(&in, &out, len, endnest, hquotes, squotes, nests,
false, c_esc, html_esc);
if (result == 0) {
/* copy endnest */
@@ -175,6 +206,8 @@ int nestlex(const char **addr, /* input string; aft points to end token */
}
--i;
}
+ } else if (result < 0) {
+ *addr = in; *token = out; return result;
}
break;
}
@@ -211,7 +244,7 @@ int nestlex(const char **addr, /* input string; aft points to end token */
}
*out++ = c;
--*len;
- if (*len == 0) {
+ if (*len <= 0) {
*addr = in;
*token = out;
return -1; /* output overflow */
@@ -222,7 +255,7 @@ int nestlex(const char **addr, /* input string; aft points to end token */
/* just a simple char */
*out++ = c;
--*len;
- if (*len == 0) {
+ if (*len <= 0) {
*addr = in;
*token = out;
return -1; /* output overflow */