mirror of
https://repo.or.cz/socat.git
synced 2024-12-23 15:52:33 +00:00
UDP-LISTEN would alway set SO_REUSEADDR even without fork option and when user set it to 0
This commit is contained in:
parent
ad200da8fd
commit
ea657bbf78
3 changed files with 74 additions and 7 deletions
3
CHANGES
3
CHANGES
|
@ -38,6 +38,9 @@ corrections:
|
||||||
socket using address GOPEN. Thanks to Martin Forssen for bug report and
|
socket using address GOPEN. Thanks to Martin Forssen for bug report and
|
||||||
patch.
|
patch.
|
||||||
|
|
||||||
|
UDP-LISTEN would alway set SO_REUSEADDR even without fork option and
|
||||||
|
when user set it to 0. Thanks to Michal Svoboda for reporting this bug.
|
||||||
|
|
||||||
docu mentions option so-bindtodev but correct name is so-bindtodevice.
|
docu mentions option so-bindtodev but correct name is so-bindtodevice.
|
||||||
Thanks to Jim Zimmerman for reporting.
|
Thanks to Jim Zimmerman for reporting.
|
||||||
|
|
||||||
|
|
58
test.sh
58
test.sh
|
@ -6115,6 +6115,63 @@ esac
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
NAME=UDPLISTENFORK
|
||||||
|
case "$TESTS" in
|
||||||
|
*%functions%*|*%ip4%*|*%udp%*|*%listen%*|*%fork%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: UDP socket rebinds after first connection"
|
||||||
|
if ! eval $NUMCOND; then :; else
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
da1="test$N $(date) $RANDOM"
|
||||||
|
da2="test$N $(date) $RANDOM"
|
||||||
|
#establish a listening and forking udp socket in background
|
||||||
|
SRV="$SOCAT $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,fork PIPE"
|
||||||
|
#make a first and a second connection
|
||||||
|
CLI="$SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT"
|
||||||
|
$PRINTF "test $F_n $TEST... " $N
|
||||||
|
eval "$SRV 2>${te}s &"
|
||||||
|
pids=$!
|
||||||
|
waitudp4port "$PORT"
|
||||||
|
echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
kill "$pids" 2>/dev/null
|
||||||
|
$PRINTF "$NO_RESULT (first conn failed):\n"
|
||||||
|
echo "$SRV &"
|
||||||
|
echo "$CLI"
|
||||||
|
cat "${te}s" "${te}1"
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
|
||||||
|
kill "$pids" 2>/dev/null
|
||||||
|
$PRINTF "$NO_RESULT (first conn failed); diff:\n"
|
||||||
|
cat "$tdiff"
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
else
|
||||||
|
sleep 2 # UDP-LISTEN sleeps 1s
|
||||||
|
echo "$da2" |eval "$CLI" >"${tf}2" 2>"${te}2"
|
||||||
|
rc="$?"; kill "$pids" 2>/dev/null
|
||||||
|
if [ $rc -ne 0 ]; then
|
||||||
|
$PRINTF "$FAILED:\n"
|
||||||
|
echo "$SRV &"
|
||||||
|
echo "$CLI"
|
||||||
|
cat "${te}s" "${te}2"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then
|
||||||
|
$PRINTF "$FAILED: diff\n"
|
||||||
|
cat "$tdiff"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
fi # !( $? -ne 0)
|
||||||
|
fi # !(rc -ne 0)
|
||||||
|
wait
|
||||||
|
fi ;; # NUMCOND, feats
|
||||||
|
esac
|
||||||
|
PORT=$((PORT+1))
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
NAME=UNIXLISTENFORK
|
NAME=UNIXLISTENFORK
|
||||||
case "$TESTS" in
|
case "$TESTS" in
|
||||||
*%functions%*|*%unix%*|*%listen%*|*%fork%*|*%$NAME%*)
|
*%functions%*|*%unix%*|*%listen%*|*%fork%*|*%$NAME%*)
|
||||||
|
@ -10786,6 +10843,7 @@ esac
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# socat up to 1.7.2.0 and 2.0.0-b4 had a bug in xioscan_readline() that could
|
# socat up to 1.7.2.0 and 2.0.0-b4 had a bug in xioscan_readline() that could
|
||||||
# be exploited
|
# be exploited
|
||||||
# to overflow a heap based buffer (socat security advisory 3)
|
# to overflow a heap based buffer (socat security advisory 3)
|
||||||
|
|
20
xio-udp.c
20
xio-udp.c
|
@ -1,5 +1,5 @@
|
||||||
/* source: xio-udp.c */
|
/* source: xio-udp.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2009 */
|
/* Copyright Gerhard Rieger 2001-2012 */
|
||||||
/* 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 handling UDP addresses */
|
/* this file contains the source for handling UDP addresses */
|
||||||
|
@ -188,7 +188,8 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
while (true) { /* we loop with fork or prohibited packets */
|
while (true) { /* we loop with fork or prohibited packets */
|
||||||
/* now wait for some packet on this datagram socket, get its sender
|
/* now wait for some packet on this datagram socket, get its sender
|
||||||
address, connect there, and return */
|
address, connect there, and return */
|
||||||
int one = 1;
|
int reuseaddr = dofork;
|
||||||
|
int doreuseaddr = (dofork != 0);
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
union sockaddr_union _sockname;
|
union sockaddr_union _sockname;
|
||||||
union sockaddr_union *la = &_sockname; /* local address */
|
union sockaddr_union *la = &_sockname; /* local address */
|
||||||
|
@ -197,12 +198,17 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
/*0 Info4("socket(%d, %d, %d) -> %d", pf, socktype, ipproto, fd->stream.fd);*/
|
/*0 Info4("socket(%d, %d, %d) -> %d", pf, socktype, ipproto, fd->stream.fd);*/
|
||||||
|
doreuseaddr |= (retropt_int(opts, OPT_SO_REUSEADDR, &reuseaddr) >= 0);
|
||||||
applyopts(fd->stream.rfd, opts, PH_PASTSOCKET);
|
applyopts(fd->stream.rfd, opts, PH_PASTSOCKET);
|
||||||
if (Setsockopt(fd->stream.rfd, opt_so_reuseaddr.major,
|
if (doreuseaddr) {
|
||||||
opt_so_reuseaddr.minor, &one, sizeof(one)) < 0) {
|
if (Setsockopt(fd->stream.rfd, opt_so_reuseaddr.major,
|
||||||
Warn6("setsockopt(%d, %d, %d, {%d}, "F_Zd"): %s",
|
opt_so_reuseaddr.minor, &reuseaddr, sizeof(reuseaddr))
|
||||||
fd->stream.rfd, opt_so_reuseaddr.major,
|
< 0) {
|
||||||
opt_so_reuseaddr.minor, one, sizeof(one), strerror(errno));
|
Warn6("setsockopt(%d, %d, %d, {%d}, "F_Zd"): %s",
|
||||||
|
fd->stream.rfd, opt_so_reuseaddr.major,
|
||||||
|
opt_so_reuseaddr.minor, reuseaddr, sizeof(reuseaddr),
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
applyopts_cloexec(fd->stream.rfd, opts);
|
applyopts_cloexec(fd->stream.rfd, opts);
|
||||||
applyopts(fd->stream.rfd, opts, PH_PREBIND);
|
applyopts(fd->stream.rfd, opts, PH_PREBIND);
|
||||||
|
|
Loading…
Reference in a new issue