Module: check_mk
Branch: master
Commit: 5af0de3414330771aa3e3f0c948a76f04a1db595
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=5af0de34143307…
Author: Andreas Boesl <ab(a)mathias-kettner.de>
Date: Wed Jun 18 11:11:13 2014 +0200
SEC Fixed various core SIGSEGV when using malformed livestatus queries
Some malformed livestatus queries could crash the monitoring core.
This happened whenever the value field for certain keys was missing.<br>
For example
C+:
lq "GET hosts\nColumnHeaders:\n"
lq "GET hosts\nAnd:\n"
lq "GET hosts\nKeepalive:\n
C-:
---
.werks/940 | 22 ++++++++++++++++++++++
ChangeLog | 3 +++
livestatus/src/Query.cc | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/.werks/940 b/.werks/940
new file mode 100644
index 0000000..e637d3f
--- /dev/null
+++ b/.werks/940
@@ -0,0 +1,22 @@
+Title: Fixed various core SIGSEGV when using malformed livestatus queries
+Level: 2
+Component: core
+Version: 1.2.5i4
+Date: 1403082179
+Class: security
+
+Some malformed livestatus queries could crash the monitoring core.
+This happened whenever the value field for certain keys was missing.<br>
+
+For example
+C+:
+
+lq "GET hosts\nColumnHeaders:\n"
+
+lq "GET hosts\nAnd:\n"
+
+lq "GET hosts\nKeepalive:\n
+
+C-:
+
+
diff --git a/ChangeLog b/ChangeLog
index 6cc5539..ed3a14c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
1.2.5i4:
+ Core & Setup:
+ * 0940 SEC: Fixed various core SIGSEGV when using malformed livestatus queries...
+
Checks & Agents:
* 0812 nginx_status: New check for monitoring status information of the Nginx web
server...
* 0986 citrix_licenses: new check for monitoring Citrix licenses
diff --git a/livestatus/src/Query.cc b/livestatus/src/Query.cc
index b7a163b..d6899e0 100644
--- a/livestatus/src/Query.cc
+++ b/livestatus/src/Query.cc
@@ -263,6 +263,13 @@ Filter *Query::createFilter(Column *column, int operator_id, char
*value)
void Query::parseAndOrLine(char *line, int andor, bool filter)
{
char *value = next_field(&line);
+ if (!value) {
+ _output->setError(RESPONSE_CODE_INVALID_HEADER, "Missing value for %s%s:
need non-zero integer number",
+ filter ? "" : "WaitCondition",
+ andor == ANDOR_OR ? "Or" : "And");
+ return;
+ }
+
int number = atoi(value);
if (!isdigit(value[0]) || number <= 0) {
_output->setError(RESPONSE_CODE_INVALID_HEADER, "Invalid value for %s%s:
need non-zero integer number",
@@ -311,6 +318,11 @@ void Query::parseNegateLine(char *line, bool filter)
void Query::parseStatsAndOrLine(char *line, int andor)
{
char *value = next_field(&line);
+ if (!value) {
+ _output->setError(RESPONSE_CODE_INVALID_HEADER, "Missing value for
Stats%s: need non-zero integer number",
+ andor == ANDOR_OR ? "Or" : "And");
+ }
+
int number = atoi(value);
if (!isdigit(value[0]) || number <= 0) {
_output->setError(RESPONSE_CODE_INVALID_HEADER, "Invalid value for
Stats%s: need non-zero integer number",
@@ -559,6 +571,12 @@ void Query::parseSeparatorsLine(char *line)
void Query::parseOutputFormatLine(char *line)
{
char *format = next_field(&line);
+ if (!format) {
+ _output->setError(RESPONSE_CODE_INVALID_HEADER,
+ "Missing output format. Only 'csv' and 'json' are
available.");
+ return;
+ }
+
if (!strcmp(format, "csv"))
_output_format = OUTPUT_FORMAT_CSV;
else if (!strcmp(format, "json"))
@@ -573,6 +591,12 @@ void Query::parseOutputFormatLine(char *line)
void Query::parseColumnHeadersLine(char *line)
{
char *value = next_field(&line);
+ if (!value) {
+ _output->setError(RESPONSE_CODE_INVALID_HEADER,
+ "Missing value for ColumnHeaders: must be 'on' or
'off'");
+ return;
+ }
+
if (!strcmp(value, "on"))
_show_column_headers = true;
else if (!strcmp(value, "off"))
@@ -585,6 +609,12 @@ void Query::parseColumnHeadersLine(char *line)
void Query::parseKeepAliveLine(char *line)
{
char *value = next_field(&line);
+ if (!value) {
+ _output->setError(RESPONSE_CODE_INVALID_HEADER,
+ "Missing value for KeepAlive: must be 'on' or
'off'");
+ return;
+ }
+
if (!strcmp(value, "on"))
_output->setDoKeepalive(true);
else if (!strcmp(value, "off"))
@@ -597,6 +627,12 @@ void Query::parseKeepAliveLine(char *line)
void Query::parseResponseHeaderLine(char *line)
{
char *value = next_field(&line);
+ if (!value) {
+ _output->setError(RESPONSE_CODE_INVALID_HEADER,
+ "Missing value for ResponseHeader: must be 'off' or
'fixed16'");
+ return;
+ }
+
if (!strcmp(value, "off"))
_output->setResponseHeader(RESPONSE_HEADER_OFF);
else if (!strcmp(value, "fixed16"))