diff options
author | Michal Srb <michalsrb@gmail.com> | 2017-03-29 17:05:45 +0300 |
---|---|---|
committer | Michal Srb <michalsrb@gmail.com> | 2017-03-30 03:25:04 +0300 |
commit | 62197c89e98be47a174074e4c7429c57767a4929 (patch) | |
tree | 97fe733b664213cf6501b6e49d58f1a7d2093d0c | |
parent | 9801c5efcf8c1774d9c807ebd5d27ac7049ad993 (diff) | |
download | tigervnc-62197c89e98be47a174074e4c7429c57767a4929.tar.gz tigervnc-62197c89e98be47a174074e4c7429c57767a4929.zip |
Limit max username/password size in SSecurityPlain.
Setting the limit to 1024 which should be still more than enough.
Unlimited ulen and plen can cause various security problems:
* Overflow in `is->checkNoWait(ulen + plen)` causing it to contine when there is not enough data and then wait forever.
* Overflow in `new char[plen + 1]` that would allocate zero sized array which succeeds but returns pointer that should not be written into.
* Allocation failure in `new char[plen + 1]` from trying to allocate too much and crashing the whole server.
All those issues can be triggered by a client before authentication.
-rw-r--r-- | common/rfb/SSecurityPlain.cxx | 7 | ||||
-rw-r--r-- | common/rfb/SSecurityPlain.h | 3 |
2 files changed, 10 insertions, 0 deletions
diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx index 05315490..fc9dff23 100644 --- a/common/rfb/SSecurityPlain.cxx +++ b/common/rfb/SSecurityPlain.cxx @@ -86,8 +86,15 @@ bool SSecurityPlain::processMsg(SConnection* sc) if (state == 0) { if (!is->checkNoWait(8)) return false; + ulen = is->readU32(); + if (ulen > MaxSaneUsernameLength) + throw AuthFailureException("Too long username"); + plen = is->readU32(); + if (plen > MaxSanePasswordLength) + throw AuthFailureException("Too long password"); + state = 1; } diff --git a/common/rfb/SSecurityPlain.h b/common/rfb/SSecurityPlain.h index 080fcd59..2c08c24e 100644 --- a/common/rfb/SSecurityPlain.h +++ b/common/rfb/SSecurityPlain.h @@ -54,6 +54,9 @@ namespace rfb { PasswordValidator* valid; unsigned int ulen, plen, state; CharArray username; + + static const unsigned int MaxSaneUsernameLength = 1024; + static const unsigned int MaxSanePasswordLength = 1024; }; } |