mirror of
https://github.com/moparisthebest/socat
synced 2024-12-21 22:48:48 -05:00
version 1.7.2.2 - fixed FD leak in accept() loop
This commit is contained in:
parent
464d23a34f
commit
022f0a46e6
10
CHANGES
10
CHANGES
@ -1,4 +1,14 @@
|
||||
|
||||
####################### V 1.7.2.2:
|
||||
|
||||
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 1.7.2.1:
|
||||
|
||||
security:
|
||||
|
61
test.sh
61
test.sh
@ -1,6 +1,6 @@
|
||||
#! /bin/bash
|
||||
# source: test.sh
|
||||
# Copyright Gerhard Rieger 2001-2012
|
||||
# Copyright Gerhard Rieger
|
||||
# Published under the GNU General Public License V.2, see file COPYING
|
||||
|
||||
# perform lots of tests on socat
|
||||
@ -10817,6 +10817,65 @@ PORT=$((PORT+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))
|
||||
|
||||
###############################################################################
|
||||
# here come tests that might affect your systems integrity. Put normal tests
|
||||
# before this paragraph.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* source: xio-listen.c */
|
||||
/* Copyright Gerhard Rieger 2001-2011 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
/* this file contains the source for listen socket options */
|
||||
@ -268,6 +268,7 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
||||
if (Shutdown(ps, 2) < 0) {
|
||||
Info2("shutdown(%d, 2): %s", ps, strerror(errno));
|
||||
}
|
||||
Close(ps);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user