mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
socat security advisory 8: stack overflow in nestlex()
This commit is contained in:
parent
20f5963f13
commit
fe2313f50f
4 changed files with 93 additions and 9 deletions
13
CHANGES
13
CHANGES
|
@ -1,5 +1,18 @@
|
|||
|
||||
security:
|
||||
Socat security advisory 8
|
||||
A stack overflow in vulnerability was found that can be triggered when
|
||||
command line arguments (complete address specifications, host names,
|
||||
file names) are longer than 512 bytes.
|
||||
Successful exploitation might allow an attacker to execute arbitrary
|
||||
code with the privileges of the socat process.
|
||||
This vulnerability can only be exploited when an attacker is able to
|
||||
inject data into socat's command line.
|
||||
A vulnerable scenario would be a CGI script that reads data from clients
|
||||
and uses (parts of) this data as hostname for a Socat invocation.
|
||||
Test: NESTEDOVFL
|
||||
Credits to Takumi Akiyama for finding and reporting this issue.
|
||||
|
||||
Socat security advisory 7
|
||||
MSVR-1499
|
||||
In the OpenSSL address implementation the hard coded 1024 bit DH p
|
||||
|
|
51
nestlex.c
51
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,18 @@
|
|||
|
||||
#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 dropspace,
|
||||
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
|
||||
|
@ -34,6 +46,23 @@ 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,
|
||||
dropspace, 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 dropspace,
|
||||
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 */
|
||||
|
@ -84,16 +113,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, 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) {
|
||||
|
@ -118,7 +149,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 */
|
||||
|
@ -132,13 +163,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, 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) {
|
||||
|
@ -171,7 +204,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, false, c_esc, html_esc);
|
||||
if (result == 0) {
|
||||
/* copy endnest */
|
||||
|
@ -184,6 +217,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;
|
||||
}
|
||||
|
@ -221,7 +256,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 */
|
||||
|
@ -233,7 +268,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 */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: nestlex.h */
|
||||
/* Copyright Gerhard Rieger 2006-2007 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __nestlex_h_included
|
||||
|
|
36
test.sh
36
test.sh
|
@ -11403,6 +11403,42 @@ esac
|
|||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
# socat up to 1.7.3.0 and to 2.0.0-b8 had a stack overflow vulnerability that occurred when
|
||||
# command line arguments (whole addresses, host names, file names) were longer
|
||||
# than 512 bytes and specially crafted.
|
||||
NAME=NESTEDOVFL
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%bugs%*|*%security%*|*%exec%*|*%$NAME%*)
|
||||
TEST="$NAME: stack overflow on overly long nested arg"
|
||||
# provide a long host name to TCP-CONNECT and check socats exit code
|
||||
if ! eval $NUMCOND; then :; else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
da="test$N $(date) $RANDOM"
|
||||
# prepare long data - perl might not be installed
|
||||
rm -f "$td/test$N.dat"
|
||||
i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
|
||||
CMD0="$TRACE $SOCAT $opts EXEC:[$(cat "$td/test$N.dat")] STDIO"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 </dev/null 1>&0 2>"${te}0"
|
||||
rc0=$?
|
||||
if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
|
||||
$PRINTF "$OK\n"
|
||||
numOK=$((numOK+1))
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0"
|
||||
cat "${te}0"
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
# test for a bug in gopen that lead to crash or warning when opening a unix
|
||||
# domain socket with GOPEN
|
||||
|
|
Loading…
Reference in a new issue