mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
Fixed possible integer overflow with option -b
This commit is contained in:
parent
0c65370ae5
commit
8e6b341f59
4 changed files with 66 additions and 2 deletions
8
CHANGES
8
CHANGES
|
@ -1,4 +1,12 @@
|
||||||
|
|
||||||
|
Security:
|
||||||
|
Buffer size option (-b) is internally doubled for CR-CRLF conversion,
|
||||||
|
but not checked for integer overflow. This could lead to heap based
|
||||||
|
buffer overflow, assuming the attacker could provide this parameter.
|
||||||
|
Test: BLKSIZE_INT_OVERFL
|
||||||
|
Thanks to Lê Hiếu Bùi for reporting this issue and sending an
|
||||||
|
example exploit.
|
||||||
|
|
||||||
Testing:
|
Testing:
|
||||||
test.sh now produces a list of tests that could not be performed for
|
test.sh now produces a list of tests that could not be performed for
|
||||||
any reason. This helps to analyse these cases.
|
any reason. This helps to analyse these cases.
|
||||||
|
|
3
procan.c
3
procan.c
|
@ -158,6 +158,9 @@ int procan(FILE *outfile) {
|
||||||
"virtual memory (kbytes) %24"F_rlim_max"%24"F_rlim_max"\n",
|
"virtual memory (kbytes) %24"F_rlim_max"%24"F_rlim_max"\n",
|
||||||
rlim.rlim_cur, rlim.rlim_max);
|
rlim.rlim_cur, rlim.rlim_max);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef SIZE_MAX
|
||||||
|
fprintf(outfile, "SIZE_MAX = %-24lu\n", SIZE_MAX);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
socat.c
4
socat.c
|
@ -779,6 +779,10 @@ int _socat(void) {
|
||||||
#endif /* WITH_FILAN */
|
#endif /* WITH_FILAN */
|
||||||
|
|
||||||
/* when converting nl to crnl, size might double */
|
/* when converting nl to crnl, size might double */
|
||||||
|
if (socat_opts.bufsiz > (SIZE_MAX-1)/2) {
|
||||||
|
Error2("buffer size option (-b) to big - "F_Zu" (max is "F_Zu")", socat_opts.bufsiz, (SIZE_MAX-1)/2);
|
||||||
|
socat_opts.bufsiz = (SIZE_MAX-1)/2;
|
||||||
|
}
|
||||||
buff = Malloc(2*socat_opts.bufsiz+1);
|
buff = Malloc(2*socat_opts.bufsiz+1);
|
||||||
if (buff == NULL) return -1;
|
if (buff == NULL) return -1;
|
||||||
|
|
||||||
|
|
53
test.sh
53
test.sh
|
@ -60,8 +60,8 @@ MISCDELAY=1
|
||||||
if ! [ -x "$SOCAT" ] && ! type $SOCAT >/dev/null 2>&1; then
|
if ! [ -x "$SOCAT" ] && ! type $SOCAT >/dev/null 2>&1; then
|
||||||
echo "$SOCAT does not exist" >&2; exit 1;
|
echo "$SOCAT does not exist" >&2; exit 1;
|
||||||
fi
|
fi
|
||||||
[ -z "$PROCAN" ] && PROCAN="./procan"
|
if [ -z "$PROCAN" ]; then if test -x ./procan; then PROCAN="./procan"; elif ! type procan >/dev/null 2>&1; then PROCAN=${SOCAT%/*}/procan; fi; fi
|
||||||
[ -z "$FILAN" ] && FILAN="./filan"
|
if [ -z "$FILAN" ]; then if test -x ./filan; then FILAN="./filan"; elif ! type filan >/dev/null 2>&1; then FILAN=${SOCAT%/*}/filan; fi; fi
|
||||||
opts="$opt_t $OPTS"
|
opts="$opt_t $OPTS"
|
||||||
export SOCAT_OPTS="$opts"
|
export SOCAT_OPTS="$opts"
|
||||||
#debug="1"
|
#debug="1"
|
||||||
|
@ -13461,6 +13461,55 @@ esac
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
# Test for integer overflow with data transfer block size parameter
|
||||||
|
NAME=BLKSIZE_INT_OVERFL
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%bugs%*|*%security%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: integer overflow with buffer size parameter"
|
||||||
|
# Use a buffer size that would lead to integer overflow
|
||||||
|
# Test succeeds when Socat terminates with correct error message
|
||||||
|
if ! eval $NUMCOND; then :; else
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
dat="$td/test$N.dat"
|
||||||
|
# calculate the minimal length with integer overflow
|
||||||
|
BYTES=$($PROCAN |grep size_t |awk '{print($3);}')
|
||||||
|
case $BYTES in
|
||||||
|
2) CHKSIZE=32768 ;;
|
||||||
|
4) CHKSIZE=2147483648 ;;
|
||||||
|
8) CHKSIZE=9223372036854775808 ;;
|
||||||
|
16) CHKSIZE=170141183460469231731687303715884105728 ;;
|
||||||
|
esac
|
||||||
|
CMD0="$TRACE $SOCAT $opts -T 1 -b $CHKSIZE /dev/null PIPE"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$CMD0 >/dev/null 2>"${te}0"
|
||||||
|
rc0=$?
|
||||||
|
if [ $rc0 -eq 0 ]; then
|
||||||
|
$PRINTF "$FAILED (rc=$rc0)\n"
|
||||||
|
echo "$CMD0"
|
||||||
|
cat "${te}0"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
elif [ $rc0 -eq 1 ]; then
|
||||||
|
if grep -q "buffer size option (-b) to big" "${te}0"; then
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$FAILED (rc=$rc0)\n"
|
||||||
|
echo "$CMD0"
|
||||||
|
cat "${te}0"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
PORT=$((PORT+1))
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
#=================================================================================
|
#=================================================================================
|
||||||
# here come tests that might affect your systems integrity. Put normal tests
|
# here come tests that might affect your systems integrity. Put normal tests
|
||||||
|
|
Loading…
Reference in a new issue