Commit 1764a5b8 authored by Leo's avatar Leo
Browse files

main/nrpe: fix CVE-2020-6581 and CVE-2020-6582

See: #11417
parent 5e6172c9
# Maintainer: Jeff Bilyk <jbilyk@gmail.com>
pkgname=nrpe
pkgver=3.2.1
pkgrel=0
pkgrel=1
pkgusers="nagios"
pkggroups="nagios"
pkgdesc="NRPE allows you to remotely execute Nagios plugins on other Linux/Unix machines."
......@@ -13,11 +13,18 @@ install="nrpe.pre-install"
subpackages="$pkgname-plugin"
source="https://downloads.sourceforge.net/nagios/$pkgname-$pkgver.tar.gz
sample-config.patch
CVE-2020-6581.patch
CVE-2020-6582.patch
nrpe.initd
nrpe.confd"
builddir="$srcdir/$pkgname-$pkgver"
options="!check" # needs services to run
# secfixes:
# 3.2.1-r1:
# - CVE-2020-6581
# - CVE-2020-6582
build() {
cd "$builddir"
......@@ -56,5 +63,7 @@ plugin() {
sha512sums="ec6ff42a00bd97ed80010a82e26dc35fd419f2feda65820cda0108068173c1ae44eee698833a50fd2079429a6f5eb1321c4f06b09c6708bc5fbe48f176389856 nrpe-3.2.1.tar.gz
f5cdf863257d75ff311767ef51679fbe437b4846a259e07e245f51c0c5abb50fb65e234cd146a73365d3c3bbd2d3c663baf9bb8827a44dc0d1f2647451729e03 sample-config.patch
296e78c9204c943a86ac3750d1fd6c741301725f50d7cb791090701baa64822ec23a1d5f5b2e690cef6ff23bb4c30b0d9ae4c6a628d0a8b056bf5d9f7d6922ac CVE-2020-6581.patch
69301b9b8429b9f6fc5fa1f70eec769e8632ebb3356ee9c1ee504539937dff96b7c0933265d0656d43b62a5f9b049bf4520a909a5dd7465732dedbf239143f88 CVE-2020-6582.patch
b2f23bab97384ef8f1760c79d0cbadb4e81d4bb8134887a38662033a7f0c30480222b9ecb78c3ae276bd8b35470b3db316143f591baa2c535f5fb26c34ad2824 nrpe.initd
05a0f1f5f75345370cae3262f9988d537e24dfcbb6c14a1ff3486193625481045d0844c035f7be491e74ca9ad45ed0fae7b7005616936cc274cd7e8a851c8628 nrpe.confd"
diff --git a/src/check_nrpe.c b/src/check_nrpe.c
index ace7041..74a2a19 100644
--- a/src/check_nrpe.c
+++ b/src/check_nrpe.c
@@ -250,7 +250,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
return ERROR;
optind = 0;
- snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:246hlnuVE");
+ snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:2346hlnuVE");
while (1) {
if (argindex > 0)
@@ -687,7 +687,7 @@ void usage(int result)
printf("SSL/TLS Available: OpenSSL 0.9.6 or higher required\n");
printf("\n");
#endif
- printf("Usage: check_nrpe -H <host> [-2] [-4] [-6] [-n] [-u] [-V] [-l] [-d <dhopt>]\n");
+ printf("Usage: check_nrpe -H <host> [-2] [-3] [-4] [-6] [-n] [-u] [-V] [-l] [-d <dhopt>]\n");
printf(" [-P <size>] [-S <ssl version>] [-L <cipherlist>] [-C <clientcert>]\n");
printf(" [-K <key>] [-A <ca-certificate>] [-s <logopts>] [-b <bindaddr>]\n");
printf(" [-f <cfg-file>] [-p <port>] [-t <interval>:<state>] [-g <log-file>]\n");
@@ -695,7 +695,8 @@ void usage(int result)
printf("\n");
printf("Options:\n");
printf(" -H, --host=HOST The address of the host running the NRPE daemon\n");
- printf(" -2, --v2-packets-only Only use version 2 packets, not version 3\n");
+ printf(" -2, --v2-packets-only Only use version 2 packets, not version 3/4\n");
+ printf(" -3, --v3-packets-only Only use version 3 packets, not version 4\n");
printf(" -4, --ipv4 Bind to ipv4 only\n");
printf(" -6, --ipv6 Bind to ipv6 only\n");
printf(" -n, --no-ssl Do no use SSL\n");
@@ -1348,14 +1349,14 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
if (rc <= 0 || rc != bytes_to_recv) {
if (rc < bytes_to_recv) {
- if (packet_ver != NRPE_PACKET_VERSION_3)
+ if (packet_ver <= NRPE_PACKET_VERSION_3)
printf("CHECK_NRPE: Receive header underflow - only %d bytes received (%ld expected).\n", rc, sizeof(bytes_to_recv));
}
return -1;
}
packet_ver = ntohs(packet.packet_version);
- if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+ if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3 && packet_ver != NRPE_PACKET_VERSION_4) {
printf("CHECK_NRPE: Invalid packet version received from server.\n");
return -1;
}
@@ -1436,14 +1437,14 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
if (rc <= 0 || rc != bytes_to_recv) {
if (rc < bytes_to_recv) {
- if (packet_ver != NRPE_PACKET_VERSION_3)
+ if (packet_ver < NRPE_PACKET_VERSION_3 || packet_ver > NRPE_PACKET_VERSION_4)
printf("CHECK_NRPE: Receive header underflow - only %d bytes received (%ld expected).\n", rc, sizeof(bytes_to_recv));
}
return -1;
}
packet_ver = ntohs(packet.packet_version);
- if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+ if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3 && packet_ver != NRPE_PACKET_VERSION_4) {
printf("CHECK_NRPE: Invalid packet version received from server.\n");
return -1;
}
diff --git a/src/nrpe.c b/src/nrpe.c
index 8e92764..c5ecc1a 100644
--- a/src/nrpe.c
+++ b/src/nrpe.c
@@ -745,6 +745,62 @@ int verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
}
#endif
+/*
+ * Given a string, convert any byte pairs representing an escape sequence (e.g. "\\r" into
+ * the single-byte metacharacter (e.g. '\r')
+ * Currently, this doesn't support octal/hex numbers or unicode code points (\n, \x, \u, \U)
+ */
+char* process_metachars(const char* input)
+{
+ char* copy = strdup(input);
+ int i,j;
+ int length = strlen(input);
+ for (i = 0, j = 0; i < length, j < length; i++, j++) {
+ if (copy[j] != '\\') {
+ copy[i] = copy[j];
+ continue;
+ }
+
+ j += 1;
+ switch (copy[j]) {
+ case 'a':
+ copy[i] = '\a';
+ break;
+ case 'b':
+ copy[i] = '\b';
+ break;
+ case 'f':
+ copy[i] = '\f';
+ break;
+ case 'n':
+ copy[i] = '\n';
+ break;
+ case 'r':
+ copy[i] = '\r';
+ break;
+ case 't':
+ copy[i] = '\t';
+ break;
+ case 'v':
+ copy[i] = '\v';
+ break;
+ case '\\':
+ copy[i] = '\\';
+ break;
+ case '\'':
+ copy[i] = '\'';
+ break;
+ case '"':
+ copy[i] = '\"';
+ break;
+ case '?':
+ copy[i] = '\?';
+ break;
+ }
+ }
+ copy[j] = '\0';
+}
+
/* read in the configuration file */
int read_config_file(char *filename)
{
@@ -1005,7 +1061,7 @@ int read_config_file(char *filename)
keep_env_vars = strdup(varvalue);
else if (!strcmp(varname, "nasty_metachars"))
- nasty_metachars = strdup(varvalue);
+ nasty_metachars = process_metachars(varvalue);
else if (!strcmp(varname, "log_file")) {
log_file = strdup(varvalue);
@@ -2010,7 +2066,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
return -1;
packet_ver = ntohs(v2_pkt->packet_version);
- if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+ if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3 && packet_ver != NRPE_PACKET_VERSION_4) {
logit(LOG_ERR, "Error: (use_ssl == false): Request packet version was invalid!");
return -1;
}
@@ -2072,7 +2128,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
return -1;
packet_ver = ntohs(v2_pkt->packet_version);
- if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+ if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3 && packet_ver != NRPE_PACKET_VERSION_4) {
logit(LOG_ERR, "Error: (use_ssl == true): Request packet version was invalid!");
return -1;
}
@@ -2081,7 +2137,13 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
buffer_size = sizeof(v2_packet) - common_size;
buff_ptr = (char *)v2_pkt + common_size;
} else {
- int32_t pkt_size = sizeof(v3_packet) - 1;
+ int32_t pkt_size = sizeof(v3_packet);
+ if (packet_ver == NRPE_PACKET_VERSION_3) {
+ pkt_size -= NRPE_V3_PACKET_SIZE_OFFSET;
+ }
+ else if (packet_ver == NRPE_PACKET_VERSION_4) {
+ pkt_size -= NRPE_V4_PACKET_SIZE_OFFSET;
+ }
/* Read the alignment filler */
bytes_to_recv = sizeof(int16_t);
@@ -2104,6 +2166,9 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
tot_bytes += rc;
buffer_size = ntohl(buffer_size);
+ if (buffer_size < 0 || buffer_size > INT_MAX - pkt_size) {
+ logit(LOG_ERR, "Error: (use_ssl == true): Received packet with invalid buffer size");
+ }
pkt_size += buffer_size;
if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
logit(LOG_ERR, "Error: (use_ssl == true): Could not allocate memory for packet");
@@ -2606,6 +2671,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
{
u_int32_t packet_crc32;
u_int32_t calculated_crc32;
+ int32_t pkt_size, buffer_size;
char *buff, *ptr;
int rc;
#ifdef ENABLE_COMMAND_ARGUMENTS
@@ -2613,8 +2679,18 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
#endif
/* check the crc 32 value */
- if (packet_ver == NRPE_PACKET_VERSION_3) {
- int32_t pkt_size = (sizeof(v3_packet) - 1) + ntohl(v3pkt->buffer_length);
+ if (packet_ver >= NRPE_PACKET_VERSION_3) {
+
+ buffer_size = ntohl(v3pkt->buffer_length);
+ if (buffer_size < 0 || buffer_size > INT_MAX - pkt_size) {
+ logit(LOG_ERR, "Error: Request packet had invalid buffer size.");
+ return ERROR;
+ }
+
+ pkt_size = sizeof(v3_packet);
+ pkt_size -= (packet_ver == NRPE_PACKET_VERSION_3 ? NRPE_V3_PACKET_SIZE_OFFSET : NRPE_V4_PACKET_SIZE_OFFSET);
+ pkt_size += buffer_size;
+
packet_crc32 = ntohl(v3pkt->crc32_value);
v3pkt->crc32_value = 0L;
v3pkt->alignment = 0;
@@ -2637,7 +2713,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
}
/* make sure buffer is terminated */
- if (packet_ver == NRPE_PACKET_VERSION_3) {
+ if (packet_ver >= NRPE_PACKET_VERSION_3) {
int32_t l = ntohs(v3pkt->buffer_length);
v3pkt->buffer[l - 1] = '\x0';
buff = v3pkt->buffer;
@@ -2653,7 +2729,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
}
/* make sure request doesn't contain nasties */
- if (packet_ver == NRPE_PACKET_VERSION_3)
+ if (packet_ver >= NRPE_PACKET_VERSION_3)
rc = contains_nasty_metachars(v3pkt->buffer);
else
rc = contains_nasty_metachars(v2pkt->buffer);
@@ -2663,7 +2739,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
}
/* make sure the request doesn't contain arguments */
- if (strchr(v2pkt->buffer, '!')) {
+ if (strchr(buff, '!')) {
#ifdef ENABLE_COMMAND_ARGUMENTS
if (allow_arguments == FALSE) {
logit(LOG_ERR, "Error: Request contained command arguments, but argument option is not enabled!");
Upstream:
https://github.com/NagiosEnterprises/nrpe/commit/b84f9b8c9d290dd02e139df8dad1c3eb690c1213
https://github.com/NagiosEnterprises/nrpe/commit/8e3bea4e1b1937e395a182729762aa8894e8649e
This is partial fix, it also requires CVE-2020-6581.patch which fixes CVE-2020-6581 and completes
the fix for this
diff --git a/include/common.h.in b/include/common.h.in
index 90f6272..3d8db5d 100644
--- a/include/common.h.in
+++ b/include/common.h.in
@@ -66,12 +66,23 @@
#define QUERY_PACKET 1 /* id code for a packet containing a query */
#define RESPONSE_PACKET 2 /* id code for a packet containing a response */
-#define NRPE_PACKET_VERSION_3 3 /* packet version identifier */
+
+/* v4 takes struct padding into account, so the buffer "takes" 4 bytes
+ * v3 removes the 1 byte that "should" be allocated to buffer.
+ */
+#define NRPE_V4_PACKET_SIZE_OFFSET 4
+#define NRPE_V3_PACKET_SIZE_OFFSET 1
+
+/* packet version identifiers */
+#define NRPE_PACKET_VERSION_4 4 /* Same as version 3, but accounts for struct padding in network code */
+#define NRPE_PACKET_VERSION_3 3 /* Allows for variable-length buffer */
#define NRPE_PACKET_VERSION_2 2
#define NRPE_PACKET_VERSION_1 1 /* older packet version identifiers (no longer supported) */
#define MAX_PACKETBUFFER_LENGTH 1024 /* amount of data to send in one query/response vor version 2 */
+#define NRPE_DEFAULT_PACKET_VERSION NRPE_PACKET_VERSION_4
+
typedef struct _v2_packet {
int16_t packet_version;
int16_t packet_type;
@@ -89,6 +100,8 @@ typedef struct _v3_packet {
char buffer[1];
} v3_packet;
+typedef v3_packet v4_packet;
+
/**************** OPERATING SYSTEM SPECIFIC DEFINITIONS **********/
#if defined(__sun) || defined(__hpux)
diff --git a/include/nrpe.h b/include/nrpe.h
index dc00c64..e1b70c0 100644
--- a/include/nrpe.h
+++ b/include/nrpe.h
@@ -24,6 +24,8 @@
*
****************************************************************************/
+#include <limits.h>
+
typedef struct command_struct {
char *command_name;
char *command_line;
diff --git a/src/check_nrpe.c b/src/check_nrpe.c
index ace7041..6107f61 100644
--- a/src/check_nrpe.c
+++ b/src/check_nrpe.c
@@ -65,8 +65,9 @@ char query[MAX_INPUT_BUFFER] = "";
int show_help = FALSE;
int show_license = FALSE;
int show_version = FALSE;
-int packet_ver = NRPE_PACKET_VERSION_3;
+int packet_ver = NRPE_DEFAULT_PACKET_VERSION;
int force_v2_packet = 0;
+int force_v3_packet = 0;
int payload_size = 0;
extern char *log_file;
@@ -175,7 +176,7 @@ int main(int argc, char **argv)
if (result == -1) {
/* Failure reading from remote, so try version 2 packet */
- logit(LOG_INFO, "Remote %s does not support Version 3 Packets", rem_host);
+ logit(LOG_INFO, "Remote %s does not support version 3/4 packets", rem_host);
packet_ver = NRPE_PACKET_VERSION_2;
/* Rerun the setup */
@@ -198,7 +199,7 @@ int main(int argc, char **argv)
}
if (result != -1 && force_v2_packet == 0 && packet_ver == NRPE_PACKET_VERSION_2)
- logit(LOG_DEBUG, "Remote %s accepted a Version %d Packet", rem_host, packet_ver);
+ logit(LOG_DEBUG, "Remote %s accepted a version %d packet", rem_host, packet_ver);
close_log_file(); /* close the log file */
return result;
@@ -224,6 +225,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
{"no-ssl", no_argument, 0, 'n'},
{"unknown-timeout", no_argument, 0, 'u'},
{"v2-packets-only", no_argument, 0, '2'},
+ {"v3-packets-only", no_argument, 0, '3'},
{"ipv4", no_argument, 0, '4'},
{"ipv6", no_argument, 0, '6'},
{"use-adh", required_argument, 0, 'd'},
@@ -366,14 +368,21 @@ int process_arguments(int argc, char **argv, int from_config_file)
break;
case '2':
- if (from_config_file && packet_ver != NRPE_PACKET_VERSION_3) {
+ if (from_config_file && packet_ver != NRPE_DEFAULT_PACKET_VERSION) {
logit(LOG_WARNING, "WARNING: Command-line v2-packets-only (-2) overrides the config file option.");
break;
}
packet_ver = NRPE_PACKET_VERSION_2;
force_v2_packet = 1;
break;
-
+ case '3':
+ if (from_config_file && packet_ver != NRPE_DEFAULT_PACKET_VERSION) {
+ logit(LOG_WARNING, "Warning: Command-line v3-packets-only (-3) overrides the config file option.");
+ break;
+ }
+ packet_ver = NRPE_PACKET_VERSION_3;
+ force_v3_packet = 1;
+ break;
case '4':
if (from_config_file && address_family != AF_UNSPEC) {
logit(LOG_WARNING, "WARNING: Command-line ipv4 (-4) or ipv6 (-6) overrides the config file option.");
@@ -526,6 +535,11 @@ int process_arguments(int argc, char **argv, int from_config_file)
return ERROR;
}
+ if (force_v2_packet && force_v3_packet) {
+ printf("Error: Only one of force_v2_packet (-2) and force_v3_packet (-3) can be specified.\n");
+ return ERROR;
+ }
+
/* make sure required args were supplied */
if (server_name == NULL && show_help == FALSE && show_version == FALSE
&& show_license == FALSE)
@@ -1165,9 +1179,13 @@ int send_request()
} else {
- pkt_size = (sizeof(v3_packet) - 1) + strlen(query) + 1;
- if (pkt_size < sizeof(v2_packet))
+ pkt_size = (sizeof(v3_packet) - NRPE_V4_PACKET_SIZE_OFFSET) + strlen(query) + 1;
+ if (packet_ver == NRPE_PACKET_VERSION_3) {
+ pkt_size = (sizeof(v3_packet) - NRPE_V3_PACKET_SIZE_OFFSET) + strlen(query) + 1;
+ }
+ if (pkt_size < sizeof(v2_packet)) {
pkt_size = sizeof(v2_packet);
+ }
v3_send_packet = calloc(1, pkt_size);
send_pkt = (char *)v3_send_packet;
@@ -1197,10 +1215,12 @@ int send_request()
}
#endif
- if (v3_send_packet)
+ if (v3_send_packet) {
free(v3_send_packet);
- if (v2_send_packet)
+ }
+ if (v2_send_packet) {
free(v2_send_packet);
+ }
if (rc == -1) {
printf("CHECK_NRPE: Error sending query to host.\n");
@@ -1214,10 +1234,11 @@ int send_request()
int read_response()
{
v2_packet *v2_receive_packet = NULL;
+ /* Note: v4 packets will use the v3_packet structure */
v3_packet *v3_receive_packet = NULL;
u_int32_t packet_crc32;
u_int32_t calculated_crc32;
- int32_t pkt_size;
+ int32_t pkt_size, buffer_size;
int rc, result;
alarm(0);
@@ -1243,32 +1264,50 @@ int read_response()
/* recv() error */
if (rc < 0) {
- if (packet_ver == NRPE_PACKET_VERSION_3) {
- if (v3_receive_packet)
- free(v3_receive_packet);
+ if (v2_receive_packet) {
+ free(v2_receive_packet);
+ }
+ if (v3_receive_packet) {
+ free(v3_receive_packet);
+ }
+ if (packet_ver >= NRPE_PACKET_VERSION_3) {
return -1;
}
- if (v2_receive_packet)
- free(v2_receive_packet);
return STATE_UNKNOWN;
} else if (rc == 0) {
/* server disconnected */
printf("CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages.\n");
- if (packet_ver == NRPE_PACKET_VERSION_3) {
- if (v3_receive_packet) {
- free(v3_receive_packet);
- }
- } else if (v2_receive_packet) {
+ if (v3_receive_packet) {
+ free(v3_receive_packet);
+ }
+ if (v2_receive_packet) {
free(v2_receive_packet);
}
return STATE_UNKNOWN;
}
/* check the crc 32 value */
- if (packet_ver == NRPE_PACKET_VERSION_3) {
- pkt_size = (sizeof(v3_packet) - 1) + ntohl(v3_receive_packet->buffer_length);
+ if (packet_ver >= NRPE_PACKET_VERSION_3) {
+
+ buffer_size = ntohl(v3_receive_packet->buffer_length);
+ if (buffer_size < 0 || buffer_size > INT_MAX - pkt_size) {
+ printf("CHECK_NRPE: Response packet had invalid buffer size.\n");
+ close(sd);
+ if (v3_receive_packet) {
+ free(v3_receive_packet);
+ }
+ if (v2_receive_packet) {
+ free(v2_receive_packet);
+ }
+ return STATE_UNKNOWN;
+ }
+
+ pkt_size = sizeof(v3_packet);
+ pkt_size -= (packet_ver == NRPE_PACKET_VERSION_3 ? NRPE_V3_PACKET_SIZE_OFFSET : NRPE_V4_PACKET_SIZE_OFFSET);
+ pkt_size += buffer_size;
+
packet_crc32 = ntohl(v3_receive_packet->crc32_value);
v3_receive_packet->crc32_value = 0L;
v3_receive_packet->alignment = 0;
@@ -1286,11 +1325,10 @@ int read_response()
if (packet_crc32 != calculated_crc32) {
printf("CHECK_NRPE: Response packet had invalid CRC32.\n");
close(sd);
- if (packet_ver == NRPE_PACKET_VERSION_3) {
- if (v3_receive_packet) {
- free(v3_receive_packet);
- }
- } else if (v2_receive_packet) {
+ if (v3_receive_packet) {
+ free(v3_receive_packet);
+ }
+ if (v2_receive_packet) {
free(v2_receive_packet);
}
return STATE_UNKNOWN;
@@ -1322,11 +1360,10 @@ int read_response()
}
}
- if (packet_ver == NRPE_PACKET_VERSION_3) {
- if (v3_receive_packet) {
- free(v3_receive_packet);
- }
- } else if (v2_receive_packet) {
+ if (v3_receive_packet) {
+ free(v3_receive_packet);
+ }
+ if (v2_receive_packet) {
free(v2_receive_packet);
}
@@ -1413,7 +1450,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
rc = recvall(sock, buff_ptr, &bytes_to_recv, socket_timeout);
if (rc <= 0 || rc != buffer_size) {
- if (packet_ver == NRPE_PACKET_VERSION_3) {
+ if (packet_ver >= NRPE_PACKET_VERSION_3) {
free(*v3_pkt);
*v3_pkt = NULL;
} else {
@@ -1517,7 +1554,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
buff_ptr[bytes_read] = 0;
if (rc < 0 || bytes_read != buffer_size) {
- if (packet_ver == NRPE_PACKET_VERSION_3) {
+ if (packet_ver >= NRPE_PACKET_VERSION_3) {
free(*v3_pkt);
*v3_pkt = NULL;
} else {
@@ -1525,7 +1562,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
*v2_pkt = NULL;
}
if (bytes_read != buffer_size) {
- if (packet_ver == NRPE_PACKET_VERSION_3) {
+ if (packet_ver >= NRPE_PACKET_VERSION_3) {
printf("CHECK_NRPE: Receive buffer size - %ld bytes received (%ld expected).\n", (long)bytes_read, sizeof(buffer_size));
} else {
printf("CHECK_NRPE: Receive underflow - only %ld bytes received (%ld expected).\n", (long)bytes_read, sizeof(buffer_size));
diff --git a/src/nrpe.c b/src/nrpe.c
index 8e92764..92d35a6 100644
--- a/src/nrpe.c
+++ b/src/nrpe.c
@@ -148,11 +148,11 @@ struct _SSL_PARMS {
SslLogging log_opts;
} sslprm = {
#if OPENSSL_VERSION_NUMBER >= 0x10100000
-NULL, NULL, NULL, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", TLSv1_plus, TRUE, 0, SSL_NoLogging};
+NULL, NULL, NULL, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", TLSv1_plus, TRUE, 0, SSL_NoLogging
#else
-NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging};
+NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging
#endif
-
+};
#ifdef HAVE_SSL
static int verify_callback(int ok, X509_STORE_CTX * ctx);
@@ -1834,7 +1834,10 @@ void handle_connection(int sock)
} else {
- pkt_size = (sizeof(v3_packet) - 1) + strlen(send_buff);
+ pkt_size = (sizeof(v3_packet) - NRPE_V4_PACKET_SIZE_OFFSET) + strlen(send_buff) + 1;
+ if (packet_ver == NRPE_PACKET_VERSION_3) {
+ pkt_size = (sizeof(v3_packet) - NRPE_V3_PACKET_SIZE_OFFSET) + strlen(send_buff) + 1;
+ }
v3_send_packet = calloc(1, pkt_size);
send_pkt = (char *)v3_send_packet;
/* initialize response packet data */
@@ -2037,6 +2040,10 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
tot_bytes += rc;
buffer_size = ntohl(buffer_size);
+ if (buffer_size < 0 || buffer_size > INT_MAX - pkt_size) {
+ logit(LOG_ERR, "Error: Received packet with invalid buffer size");
+ return -1;
+ }
pkt_size += buffer_size;
if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
logit(LOG_ERR, "Error: (use_ssl == false): Could not allocate memory for packet");
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment