diff -r -N -U 3 socat-1.7.2.2/CHANGES socat-1.7.2.3/CHANGES --- socat-1.7.2.2/CHANGES 2013-03-25 17:36:42.000000000 +0100 +++ socat-1.7.2.3/CHANGES 2014-01-28 18:39:01.000000000 +0100 @@ -1,4 +1,11 @@ +####################### V 1.7.2.3: + +security: + CVE-2014-0019: socats PROXY-CONNECT address was vulnerable to a buffer + overflow with data from command line (see socat-secadv5.txt) + Credits to Florian Weimer of the Red Hat Product Security Team + ####################### V 1.7.2.2: security: diff -r -N -U 3 socat-1.7.2.2/VERSION socat-1.7.2.3/VERSION --- socat-1.7.2.2/VERSION 2013-03-25 17:42:07.000000000 +0100 +++ socat-1.7.2.3/VERSION 2014-01-28 18:39:01.000000000 +0100 @@ -1 +1 @@ -"1.7.2.2" +"1.7.2.3" diff -r -N -U 3 socat-1.7.2.2/test.sh socat-1.7.2.3/test.sh --- socat-1.7.2.2/test.sh 2013-03-22 07:43:41.000000000 +0100 +++ socat-1.7.2.3/test.sh 2014-01-28 18:39:01.000000000 +0100 @@ -49,6 +49,9 @@ #SOCAT_EGD="egd=/dev/egd-pool" MISCDELAY=1 [ -z "$SOCAT" ] && SOCAT="./socat" +if [ ! -x "$SOCAT" ]; then + echo "$SOCAT does not exist" >&2; exit 1; +fi [ -z "$PROCAN" ] && PROCAN="./procan" [ -z "$FILAN" ] && FILAN="./filan" opts="$opt_t $OPTS" @@ -10876,6 +10879,56 @@ PORT=$((PORT+1)) N=$((N+1)) + +if false; then # this overflow is not reliably reproducable +# socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command line paramters when copying them into the HTTP request buffer. This could lead to a buffer overflow. +NAME=PROXY_ADDR_OVFL +case "$TESTS" in +*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*) +TEST="$NAME: proxy address parameters overflow" +# invoke socat PROXY-CONNECT with long proxy server and target server names. If it terminates with exit code >= 128 it is vulnerable +# However, even if vulnerable it often does not crash. Therefore we try to use a boundary check program like ElectricFence; only with its help we can tell that clean run proofs absence of vulnerability +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" +EF=; for p in ef; do + if type ef >/dev/null 2>&1; then + EF="ef "; break + fi +done +CMD0="$SOCAT $opts TCP-LISTEN:$PORT,reuseaddr FILE:/dev/null" +#CMD1="$EF $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$(perl -e "print 'A' x 256"):$(perl -e "print 'A' x 256"):80" +CMD1="$EF $SOCAT $opts FILE:/dev/null PROXY-CONNECT:localhost:$(perl -e "print 'A' x 384"):80,proxyport=$PORT" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" & +pid0=$! +waittcp4port $PORT 1 +$CMD1 >/dev/null 2>"${te}1" +rc1=$? +if [ $rc1 -lt 128 ]; then + if [ "$EF" ]; then + $PRINTF "$OK\n" + numOK=$((numOK+1)) + else + $PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n" + numCANT=$((num+1)) + fi +else + $PRINTF "$FAILED\n" + echo "$CMD1" + cat "${te}" + numFAIL=$((numFAIL+1)) +fi +fi # NUMCOND + ;; +esac +PORT=$((PORT+1)) +N=$((N+1)) +fi # false + + ############################################################################### # here come tests that might affect your systems integrity. Put normal tests # before this paragraph. diff -r -N -U 3 socat-1.7.2.2/xio-proxy.c socat-1.7.2.3/xio-proxy.c --- socat-1.7.2.2/xio-proxy.c 2011-12-06 08:45:03.000000000 +0100 +++ socat-1.7.2.3/xio-proxy.c 2014-01-28 18:39:01.000000000 +0100 @@ -1,5 +1,5 @@ /* source: xio-proxy.c */ -/* Copyright Gerhard Rieger 2002-2011 */ +/* Copyright Gerhard Rieger */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of HTTP proxy CONNECT @@ -275,8 +275,9 @@ struct proxyvars *proxyvars, int level) { size_t offset; - char request[CONNLEN]; - char buff[BUFLEN+1]; + char request[CONNLEN]; /* HTTP connection request line */ + int rv; + char buff[BUFLEN+1]; /* for receiving HTTP reply headers */ #if CONNLEN > BUFLEN #error not enough buffer space #endif @@ -286,8 +287,12 @@ ssize_t sresult; /* generate proxy request header - points to final target */ - sprintf(request, "CONNECT %s:%u HTTP/1.0\r\n", - proxyvars->targetaddr, proxyvars->targetport); + rv = snprintf(request, CONNLEN, "CONNECT %s:%u HTTP/1.0\r\n", + proxyvars->targetaddr, proxyvars->targetport); + if (rv >= CONNLEN || rv < 0) { + Error("_xioopen_proxy_connect(): PROXY CONNECT buffer too small"); + return -1; + } /* send proxy CONNECT request (target addr+port) */ * xiosanitize(request, strlen(request), textbuff) = '\0';