mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Fixed a bug in dalan that could lead to SIGSEGV
This commit is contained in:
parent
9368c5576d
commit
67027cee59
3 changed files with 119 additions and 14 deletions
4
CHANGES
4
CHANGES
|
@ -9,6 +9,10 @@ Corrections:
|
||||||
the ip-add-source-membership option.
|
the ip-add-source-membership option.
|
||||||
Thanks to Benjamin Poirier for sending a patch.
|
Thanks to Benjamin Poirier for sending a patch.
|
||||||
|
|
||||||
|
Fixed a bug in dalan module that caused SIGSEGV in, e.g.,
|
||||||
|
SOCKET-LISTEN:1:1:'"/tmp/sock"'
|
||||||
|
Test: DALAN_NO_SIGSEGV
|
||||||
|
|
||||||
Coding:
|
Coding:
|
||||||
New Environment variable SOCAT_TRANSFER_WAIT that Socat sleep before
|
New Environment variable SOCAT_TRANSFER_WAIT that Socat sleep before
|
||||||
starting the data transfer loop. Useful, e.g., to accumulate multiple
|
starting the data transfer loop. Useful, e.g., to accumulate multiple
|
||||||
|
|
10
dalan.c
10
dalan.c
|
@ -285,7 +285,7 @@ static int dalan_item(int c, const char **line0, uint8_t *data, size_t *p, size_
|
||||||
|
|
||||||
/* read data description from line (\0-terminated), write result to data; do
|
/* read data description from line (\0-terminated), write result to data; do
|
||||||
not write so much data that *p exceeds n !
|
not write so much data that *p exceeds n !
|
||||||
p must be initialized to 0.
|
*p must be initialized.
|
||||||
return 0 on success,
|
return 0 on success,
|
||||||
-1 if the data was cut due to n limit,
|
-1 if the data was cut due to n limit,
|
||||||
1 if a syntax error occurred
|
1 if a syntax error occurred
|
||||||
|
@ -310,9 +310,15 @@ int dalan(const char *line, uint8_t *data, size_t *p, size_t n, char deflt) {
|
||||||
/* white space */
|
/* white space */
|
||||||
continue;
|
continue;
|
||||||
} else if (rc == 3) {
|
} else if (rc == 3) {
|
||||||
/* no, we did not recognize c as type specifier, try default type */
|
const char *line0;
|
||||||
--line;
|
--line;
|
||||||
|
line0 = line;
|
||||||
|
/* No, we did not recognize c as type specifier, try default type */
|
||||||
rc = dalan_item(deflt, &line, data, p, n);
|
rc = dalan_item(deflt, &line, data, p, n);
|
||||||
|
if (line == line0) {
|
||||||
|
/* Nothing was parsed */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
return rc;
|
return rc;
|
||||||
|
|
119
test.sh
119
test.sh
|
@ -549,8 +549,8 @@ case "$TESTS" in
|
||||||
$ECHO "testing if address array is sorted...\c"
|
$ECHO "testing if address array is sorted...\c"
|
||||||
TF="$TD/socat-q"
|
TF="$TD/socat-q"
|
||||||
IFS="$($ECHO ' \n\t')"
|
IFS="$($ECHO ' \n\t')"
|
||||||
$SOCAT -? |sed '1,/address-head:/ d' |egrep 'groups=' |while IFS="$IFS:" read x y; do echo "$x"; done >"$TF"
|
$SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' >"$TF"
|
||||||
$SOCAT -? |sed '1,/address-head:/ d' |egrep 'groups=' |while IFS="$IFS:" read x y; do echo "$x"; done |LC_ALL=C sort |diff "$TF" - >"$TF-diff"
|
$SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' |LC_ALL=C sort |diff "$TF" - >"$TF-diff"
|
||||||
if [ -s "$TF-diff" ]; then
|
if [ -s "$TF-diff" ]; then
|
||||||
$ECHO "\n*** address array is not sorted. Wrong entries:" >&2
|
$ECHO "\n*** address array is not sorted. Wrong entries:" >&2
|
||||||
cat "$TD/socat-q-diff" >&2
|
cat "$TD/socat-q-diff" >&2
|
||||||
|
@ -15676,8 +15676,8 @@ for addr in exec system; do
|
||||||
tdiff="$td/test$N.diff"
|
tdiff="$td/test$N.diff"
|
||||||
da="test$N $(date) $RANDOM"
|
da="test$N $(date) $RANDOM"
|
||||||
#CMD0="$TRACE $SOCAT $opts -lp server -T 2 UNIX-SENDTO:$ts1,bind=$ts0 $ADDR:\"$SOCAT -lp echoer -u - -\",pty,echo=0,pipes" # test the test
|
#CMD0="$TRACE $SOCAT $opts -lp server -T 2 UNIX-SENDTO:$ts1,bind=$ts0 $ADDR:\"$SOCAT -lp echoer -u - -\",pty,echo=0,pipes" # test the test
|
||||||
CMD0="$TRACE $SOCAT $opts -lp server -T 2 UNIX-SENDTO:$ts1,bind=$ts0 $ADDR:\"$SOCAT -lp echoer -u - -\",socktype=$SOCK_DGRAM"
|
CMD0="$TRACE $SOCAT $opts -lp server -T 2 UNIX-SENDTO:$ts1,bind=$ts0,null-eof $ADDR:\"$SOCAT -lp echoer -u - -\",socktype=$SOCK_DGRAM",shut-null
|
||||||
CMD1="$SOCAT $opts -lp client -b 24 -t 2 -T 3 - UNIX-SENDTO:$ts0,bind=$ts1"
|
CMD1="$SOCAT $opts -lp client -b 24 -t 2 -T 3 - UNIX-SENDTO:$ts0,bind=$ts1",shut-null
|
||||||
printf "test $F_n $TEST... " $N
|
printf "test $F_n $TEST... " $N
|
||||||
export SOCAT_TRANSFER_WAIT=2
|
export SOCAT_TRANSFER_WAIT=2
|
||||||
eval "$CMD0" >/dev/null 2>"${te}0" &
|
eval "$CMD0" >/dev/null 2>"${te}0" &
|
||||||
|
@ -15720,6 +15720,56 @@ for addr in exec system; do
|
||||||
done # for
|
done # for
|
||||||
|
|
||||||
|
|
||||||
|
# Test if a special quote based syntax error in dalan module does not raise
|
||||||
|
# SIGSEGV
|
||||||
|
NAME=DALAN_NO_SIGSEGV
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%bugs%*|*%dalan%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: Dalan syntax error does not raise SIGSEGV"
|
||||||
|
# Invoke Socat with an address that has this quote based syntax error.
|
||||||
|
# When exit code is 1 (due to syntax error) the test succeeded.
|
||||||
|
if ! eval $NUMCOND; then :
|
||||||
|
elif ! a=$(testfeats GOPEN); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! a=$(testaddrs - GOPEN SOCKET-LISTEN); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
else
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
da="test$N $(date) $RANDOM"
|
||||||
|
CMD="$TRACE $SOCAT $opts /dev/null SOCKET-LISTEN:1:1:'"/tmp/sock"'"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$CMD >/dev/null 2>"${te}"
|
||||||
|
rc1=$?
|
||||||
|
if [ $rc1 -eq 1 ]; then
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
if [ "$VERBOSE" ]; then echo "$CMD"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}" >&2; fi
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
elif [ $rc1 -eq 139 ]; then
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD"
|
||||||
|
cat "${te}" >&2
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
else
|
||||||
|
# soemthing unexpected happened
|
||||||
|
$PRINTF "$CANT\n"
|
||||||
|
echo "$CMD"
|
||||||
|
cat "${te}" >&2
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
fi
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
# end of common tests
|
# end of common tests
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
|
@ -15827,38 +15877,83 @@ case "$TESTS" in
|
||||||
*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
|
*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
|
||||||
TEST="$NAME: give a one line description of test"
|
TEST="$NAME: give a one line description of test"
|
||||||
# Describe how the test is performed, and what's the success criteria
|
# Describe how the test is performed, and what's the success criteria
|
||||||
if ! eval $NUMCOND; then :; else
|
if ! eval $NUMCOND; then :;
|
||||||
|
# Remove unneeded checks, adapt lists of the remaining ones
|
||||||
|
elif [ "$UNAME" != Linux ]; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! $(type systemd-socket-activate >/dev/null 2>&1); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! a=$(testfeats STDIO IP4 TCP PIPE); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! a=$(testaddrs - TCP4 TCP4-LISTEN PIPE); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! o=$(testoptions so-reuseaddr fork ) >/dev/null; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! runsip4 >/dev/null; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif [ -z "$FOREIGN" ]; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
else
|
||||||
tf="$td/test$N.stdout"
|
tf="$td/test$N.stdout"
|
||||||
te="$td/test$N.stderr"
|
te="$td/test$N.stderr"
|
||||||
tdiff="$td/test$N.diff"
|
tdiff="$td/test$N.diff"
|
||||||
da="test$N $(date) $RANDOM"
|
da="test$N $(date) $RANDOM"
|
||||||
|
newport tcp4 # or whatever proto, or drop this line
|
||||||
CMD0="$TRACE $SOCAT $opts server-address PIPE"
|
CMD0="$TRACE $SOCAT $opts server-address PIPE"
|
||||||
CMD1="$TRACE $SOCAT $opts - client-address"
|
CMD1="$TRACE $SOCAT $opts - client-address"
|
||||||
printf "test $F_n $TEST... " $N
|
printf "test $F_n $TEST... " $N
|
||||||
$CMD0 >/dev/null 2>"${te}0" &
|
$CMD0 >/dev/null 2>"${te}0" &
|
||||||
pid0=$!
|
pid0=$!
|
||||||
wait<something>port $PORT 1
|
wait<something>port $PORT 1
|
||||||
|
#relsleep 1 # if no matching wait*port function
|
||||||
echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
|
echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
|
||||||
rc1=$?
|
rc1=$?
|
||||||
kill $pid0 2>/dev/null; wait
|
kill $pid0 2>/dev/null; wait
|
||||||
if [ !!! ]; then
|
if [ !!! ]; then
|
||||||
$PRINTF "$OK\n"
|
$PRINTF "$OK\n"
|
||||||
if [ "$VERBOSE" ]; then
|
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||||
echo "$CMD0 &" >&2
|
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||||
echo "$CMD1" >&2
|
if [ "$VERBOSE" ]; then echo "$CMD1"; fi
|
||||||
fi
|
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||||
numOK=$((numOK+1))
|
numOK=$((numOK+1))
|
||||||
|
elif [ !!! ]; then
|
||||||
|
# The test could not run meaningfully
|
||||||
|
$PRINTF "$CANT\n"
|
||||||
|
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||||
|
if [ "$VERBOSE" ]; then echo "$CMD1"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
else
|
else
|
||||||
$PRINTF "$FAILED\n"
|
$PRINTF "$FAILED\n"
|
||||||
echo "$CMD0 &" >&2
|
echo "$CMD0 &"
|
||||||
cat "${te}0" >&2
|
cat "${te}0" >&2
|
||||||
echo "$CMD1" >&2
|
echo "$CMD1"
|
||||||
cat "${te}1" >&2
|
cat "${te}1" >&2
|
||||||
numFAIL=$((numFAIL+1))
|
numFAIL=$((numFAIL+1))
|
||||||
listFAIL="$listFAIL $N"
|
listFAIL="$listFAIL $N"
|
||||||
|
namesFAIL="$namesFAIL $NAME"
|
||||||
fi
|
fi
|
||||||
fi # NUMCOND
|
fi # NUMCOND
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
PORT=$((PORT+1))
|
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
Loading…
Reference in a new issue