From cdc97d3e55cf029dbdd91dfa213700af9714a41a Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Wed, 10 Jul 2019 21:24:45 +0100 Subject: Fix some potential buffer overflows when sending to client/server. --- functions.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'functions.c') 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; } -- cgit v1.2.3