diff options
author | Daiki Ueno <ueno@gnu.org> | 2020-10-30 16:53:47 +0100 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2020-10-31 16:18:34 +0100 |
commit | 9728b396db737987bbd3a1d1e4a17449b6b928fc (patch) | |
tree | a6ec2e2464c0addb5377e7fb605bc64dd6f5c186 | |
parent | cc89b3c82a13fc88a6fbfb1e4d47278bebcf913a (diff) | |
download | gnutls-9728b396db737987bbd3a1d1e4a17449b6b928fc.tar.gz |
psktool: Fix hex-encoding logic of username
The previous code didn't modify the pointer to the realloc'ed region
nor check overflow before calling realloc.
Spotted by Anderson Sasaki in:
<https://gitlab.com/gnutls/gnutls/-/merge_requests/1345#note_439063374>.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
-rw-r--r-- | src/psk.c | 15 | ||||
-rwxr-xr-x | tests/psktool.sh | 32 |
2 files changed, 41 insertions, 6 deletions
@@ -58,6 +58,7 @@ int main(int argc, char **argv) #include <minmax.h> #include "close-stream.h" #include "getpass.h" +#include "xsize.h" static int write_key(const char *username, const unsigned char *key, size_t key_size, @@ -217,6 +218,7 @@ write_key(const char *username, const unsigned char *key, size_t key_size, /* encode username if it contains special characters */ if (strcspn(username, ":\n") != strlen(username)) { char *new_data; + size_t new_size; tmp.data = (void *)username; tmp.size = strlen(username); @@ -229,16 +231,21 @@ write_key(const char *username, const unsigned char *key, size_t key_size, } /* prepend '#' */ - new_data = gnutls_realloc(_username.data, _username.size + 2); + new_size = xsum(_username.size, 2); + if (size_overflow_p(new_size)) { + ret = -1; + goto out; + } + new_data = gnutls_realloc(_username.data, new_size); if (!new_data) { ret = -1; goto out; } - memmove(_username.data + 1, _username.data, _username.size); + memmove(new_data + 1, new_data, _username.size); new_data[0] = '#'; - new_data[_username.size] = '\0'; + new_data[_username.size + 1] = '\0'; _username.data = (void *)new_data; - _username.size += 1; + _username.size = new_size - 1; } else { _username.data = (void *)strdup(username); _username.size = strlen(username); diff --git a/tests/psktool.sh b/tests/psktool.sh index 9e81d01718..9d0e081296 100755 --- a/tests/psktool.sh +++ b/tests/psktool.sh @@ -41,7 +41,7 @@ fi echo "Checking PSK tool basic operations" # echo create a user and check whether a key is available -"${PSKTOOL}" -p ${TMPFILE} -u test +${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u test if test $? != 0;then echo "password generation failed..." exit 1 @@ -63,7 +63,7 @@ fi # Create second user and check whether both exist -"${PSKTOOL}" -p ${TMPFILE} -u user2 +${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u user2 if test $? != 0;then echo "password generation failed..." exit 1 @@ -81,6 +81,34 @@ if test $? != 0;then exit 1 fi +# Create third user with a special character in username + +${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u user:3 +if test $? != 0;then + echo "password generation failed..." + exit 1 +fi + +grep '#757365723a33:' ${TMPFILE} >/dev/null 2>&1 +if test $? != 0;then + echo "could not find third generated user..." + exit 1 +fi + +# Modify the third user password + +${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u user:3 +if test $? != 0;then + echo "password generation failed..." + exit 1 +fi + +matches=`grep '#757365723a33:' ${TMPFILE} 2>/dev/null | wc -l` +if test $matches != 1;then + echo "duplicate entry for third generated user..." + exit 1 +fi + rm -f $TMPFILE exit 0 |