diff options
author | Luke Bratch <luke@bratch.co.uk> | 2019-07-10 21:24:45 +0100 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2019-07-10 21:24:45 +0100 |
commit | cdc97d3e55cf029dbdd91dfa213700af9714a41a (patch) | |
tree | d006444aa5f0bb77a390e39f20614803ae62da7a | |
parent | b9a8951cf86214a3dcb430ae0d34e8d5dc1adb11 (diff) |
Fix some potential buffer overflows when sending to client/server.
-rw-r--r-- | functions.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/functions.c b/functions.c index 938b8b1..a1faf16 100644 --- a/functions.c +++ b/functions.c @@ -395,9 +395,13 @@ int arrindex(struct client *clients, int clientfd) { // Send whatever string to a specific client by providing the FD // If "bypass" == 1 then permit sending to client even if unauthenticated (for instance for a CAP LS response) int sendtoclient(int fd, char *strsrc, struct client *clients, struct settings *settings, int bypass) { - if (strlen(strsrc) > MAXDATASIZE) { + if (strlen(strsrc) >= MAXDATASIZE) { // String is too long! - debugprint(DEBUG_CRIT, "sendtoclient(): strsrc '%s' was too long (%d out of a max of %d characters).\n", strsrc, strlen(strsrc), MAXDATASIZE); + debugprint(DEBUG_CRIT, "sendtoclient(): strsrc '%s' was too long (%d out of a max of %d characters).\n", strsrc, strlen(strsrc), MAXDATASIZE - 1); + return 0; + } else if (strlen(strsrc) >= MAXDATASIZE - 2 && strsrc[strlen(strsrc) - 1] != '\r' && strsrc[strlen(strsrc)] != '\n') { + // Ensure string can fit CRLF at the end if it doesn't already have it + debugprint(DEBUG_CRIT, "sendtoclient(): non-CRLF message too long to append CRLF to.\n"); return 0; } @@ -436,9 +440,13 @@ int sendtoclient(int fd, char *strsrc, struct client *clients, struct settings * int sendtoallclients(struct client *clients, char *strsrc, int except, struct settings *settings) { char *sendertype; - if (strlen(strsrc) > MAXDATASIZE) { + if (strlen(strsrc) >= MAXDATASIZE) { // String is too long! - debugprint(DEBUG_CRIT, "sendtoallclients(): strsrc '%s' was too long (%d out of a max of %d characters).\n", strsrc, strlen(strsrc), MAXDATASIZE); + debugprint(DEBUG_CRIT, "sendtoallclients(): strsrc '%s' was too long (%d out of a max of %d characters).\n", strsrc, strlen(strsrc), MAXDATASIZE - 1); + return 0; + } else if (strlen(strsrc) >= MAXDATASIZE - 2 && strsrc[strlen(strsrc) - 1] != '\r' && strsrc[strlen(strsrc)] != '\n') { + // Ensure string can fit CRLF at the end if it doesn't already have it + debugprint(DEBUG_CRIT, "sendtoallclients(): non-CRLF message too long to append CRLF to.\n"); return 0; } @@ -502,9 +510,13 @@ int sendtoallclients(struct client *clients, char *strsrc, int except, struct se // from a real client. // Returns 1 on success or 0 on failure. - TODO - Make callers care about this. int sendtoserver(SSL *server_ssl, char *strsrc, int str_len, int clientfd, struct client *clients, struct settings *settings) { - if (strlen(strsrc) > MAXDATASIZE) { + if (strlen(strsrc) >= MAXDATASIZE) { // String is too long! - debugprint(DEBUG_CRIT, "sendtoserver(): strsrc '%s' was too long (%d out of a max of %d characters).\n", strsrc, strlen(strsrc), MAXDATASIZE); + debugprint(DEBUG_CRIT, "sendtoserver(): strsrc '%s' was too long (%d out of a max of %d characters).\n", strsrc, strlen(strsrc), MAXDATASIZE - 1); + return 0; + } else if (strlen(strsrc) >= MAXDATASIZE - 2 && strsrc[strlen(strsrc) - 1] != '\r' && strsrc[strlen(strsrc)] != '\n') { + // Ensure string can fit CRLF at the end if it doesn't already have it + debugprint(DEBUG_CRIT, "sendtoserver(): non-CRLF message too long to append CRLF to.\n"); return 0; } |