diff --git a/CHANGES b/CHANGES index 6212999..3e29e24 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,11 @@ Security: Thanks to Lê Hiếu Bùi for reporting this issue and sending an example exploit. +Corrections: + Socats address parser read over end of string when there were unbalanced + quotes + Test: UNBALANCED_QUOTE + Testing: test.sh now produces a list of tests that could not be performed for any reason. This helps to analyse these cases. diff --git a/nestlex.c b/nestlex.c index 329c162..b64dd38 100644 --- a/nestlex.c +++ b/nestlex.c @@ -159,6 +159,7 @@ static int _nestlex(const char **addr, if (result == 0 && dropquotes) { /* we strip the trailing quote */ + if (!in[0] || strncmp(in, *quotx, strlen(*quotx))) return 1; in += strlen(*quotx); } else if (result < 0) { *addr = in; *token = out; return result; diff --git a/test.sh b/test.sh index 6407a89..adc2f39 100755 --- a/test.sh +++ b/test.sh @@ -13510,6 +13510,37 @@ PORT=$((PORT+1)) N=$((N+1)) +# Test if unbalanced quoting in Socat addresses is detected +NAME=UNBALANCED_QUOTE +case "$TESTS" in +*%$N%*|*%functions%*|*%bugs%*|*%$NAME%*) +TEST="$NAME: Test fix of unbalanced quoting" +# Invoke Socat with an address containing unbalanced quoting. If Socat prints +# a "syntax error" message, the test succeeds +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" +CMD0="$TRACE $SOCAT $opts -u FILE:$td/ab\"cd FILE:/dev/null" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" +if grep -q "syntax error" "${te}0"; then + $PRINTF "$OK\n" + numOK=$((numOK+1)) +else + $PRINTF "$FAILED\n" + echo "$CMD0" + cat "${te}0" + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + ################################################################################## #================================================================================= # here come tests that might affect your systems integrity. Put normal tests diff --git a/xioopen.c b/xioopen.c index dbb6568..dbef43a 100644 --- a/xioopen.c +++ b/xioopen.c @@ -367,6 +367,8 @@ xiofile_t *xioopen(const char *addr, /* address specification */ return NULL; } + Debug1("xioopen(\"%s\")", addr); + if ((xfd = xioparse_dual(&addr)) == NULL) { return NULL; } @@ -384,6 +386,8 @@ xiofile_t *xioopen(const char *addr, /* address specification */ return xfd; } +/* parse an address string that might contain !! + return NULL on error */ static xiofile_t *xioparse_dual(const char **addr) { xiofile_t *xfd; xiosingle_t *sfd1; @@ -445,6 +449,7 @@ static int xioopen_dual(xiofile_t *xfd, int xioflags) { static xiosingle_t *xioparse_single(const char **addr) { + const char *addr0 = *addr; /* save for error messages */ xiofile_t *xfd; xiosingle_t *sfd; struct addrname *ae; @@ -540,7 +545,7 @@ static xiosingle_t *xioparse_single(const char **addr) { len = sizeof(token); tokp = token; if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) != 0) { - Error2("syntax error in address \"%s%s\"", token, *addr); + Error1("syntax error in address \"%s\"", addr0); } *tokp = '\0'; if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) {