mirror of
https://repo.or.cz/socat.git
synced 2024-12-23 07:52:32 +00:00
version 2.0.0-b6 - fixed FD leak in accept() loop
This commit is contained in:
parent
2d24bc3157
commit
c22863e4fb
4 changed files with 74 additions and 3 deletions
10
CHANGES
10
CHANGES
|
@ -1,4 +1,14 @@
|
||||||
|
|
||||||
|
####################### V 2.0.0-b6:
|
||||||
|
|
||||||
|
security:
|
||||||
|
after refusing a client connection due to bad source address or source
|
||||||
|
port socat shutdown() the socket but did not close() it, resulting in
|
||||||
|
a file descriptor leak in the listening process, visible with lsof and
|
||||||
|
possibly resulting in EMFILE Too many open files. This issue could be
|
||||||
|
misused for a denial of service attack.
|
||||||
|
Full credits to Catalin Mitrofan for finding and reporting this issue.
|
||||||
|
|
||||||
####################### V 2.0.0-b5:
|
####################### V 2.0.0-b5:
|
||||||
|
|
||||||
security:
|
security:
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
"2.0.0-b5"
|
"2.0.0-b6"
|
||||||
|
|
62
test.sh
62
test.sh
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
# source: test.sh
|
# source: test.sh
|
||||||
# Copyright Gerhard Rieger 2001-2012
|
# Copyright Gerhard Rieger
|
||||||
# Published under the GNU General Public License V.2, see file COPYING
|
# Published under the GNU General Public License V.2, see file COPYING
|
||||||
|
|
||||||
# perform lots of tests on socat
|
# perform lots of tests on socat
|
||||||
|
@ -10626,6 +10626,66 @@ PORT=$((PORT+1))
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
# socat up to 1.7.2.1 did only shutdown() but not close() an accept() socket
|
||||||
|
# that was rejected due to range, tcpwrap, lowport, or sourceport option.
|
||||||
|
# This file descriptor leak could be used for a denial of service attack.
|
||||||
|
NAME=FDLEAK
|
||||||
|
case "$TESTS" in
|
||||||
|
*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: file descriptor leak with range option"
|
||||||
|
# have a TCP-LISTEN with range option; connect with wrong source address until
|
||||||
|
# "open files" limit would exceed. When server continues operation the bug is
|
||||||
|
# not present.
|
||||||
|
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"
|
||||||
|
RLIMIT_NOFILE="$(ulimit -n)"
|
||||||
|
if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then
|
||||||
|
$PRINTF "${YELLOW}cannot determine ulimit -n"
|
||||||
|
else
|
||||||
|
CMD0="$SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,range=$LOCALHOST:255.255.255.255 PIPE"
|
||||||
|
CMD1="$SOCAT $opts -t 0 /dev/null TCP:$SECONDADDR:$PORT"
|
||||||
|
CMD2="$SOCAT $opts - TCP:$LOCALHOST:$PORT"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$CMD0 >/dev/null 2>"${te}0" &
|
||||||
|
pid0=$!
|
||||||
|
waittcp4port $PORT 1
|
||||||
|
while [ $RLIMIT_NOFILE -gt 0 ]; do
|
||||||
|
$CMD1 >/dev/null 2>>"${te}1"
|
||||||
|
let RLIMIT_NOFILE=RLIMIT_NOFILE-1
|
||||||
|
done
|
||||||
|
echo "$da" |$CMD2 >"${tf}2" 2>"${te}2"
|
||||||
|
rc2=$?
|
||||||
|
kill $pid0 2>/dev/null; wait
|
||||||
|
echo -e "$da" |diff "${tf}2" - >$tdiff
|
||||||
|
if [ $rc2 -ne 0 ]; then
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD2 &"
|
||||||
|
cat "${te}2"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
echo "$CMD1"
|
||||||
|
echo "$CMD2"
|
||||||
|
cat "${te}0"
|
||||||
|
cat "${te}1"
|
||||||
|
cat "${te}2"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
fi
|
||||||
|
fi # ulimit -n
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
PORT=$((PORT+1))
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
|
echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* source: xio-listen.c */
|
/* source: xio-listen.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2009 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
/* this file contains the source for listen socket options */
|
/* this file contains the source for listen socket options */
|
||||||
|
@ -270,6 +270,7 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
||||||
if (Shutdown(ps, 2) < 0) {
|
if (Shutdown(ps, 2) < 0) {
|
||||||
Info2("shutdown(%d, 2): %s", ps, strerror(errno));
|
Info2("shutdown(%d, 2): %s", ps, strerror(errno));
|
||||||
}
|
}
|
||||||
|
Close(ps);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue