Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ZBX-23855] Possible buffer overread from reading DNS responses (CVE-2023-32726) #48

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 57 additions & 10 deletions src/libs/zbxsysinfo/common/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,8 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans
{
if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL,
"Cannot decode DNS response: cannot expand domain name."));
ret = SYSINFO_RET_FAIL;
goto clean;
}
Expand All @@ -651,6 +652,13 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans
GETSHORT(q_len, msg_ptr);
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type));

if (msg_ptr + q_len > msg_end)
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response: record overflow."));
ret = SYSINFO_RET_FAIL;
goto clean;
}

switch (q_type)
{
case T_A:
Expand Down Expand Up @@ -695,8 +703,40 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans
case T_PTR:
if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr)))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
#define ERR_MSG_PREFIX "Cannot decode DNS response: cannot expand "
const char *err_msg = NULL;

switch (q_type)
{
case T_NS:
err_msg = ERR_MSG_PREFIX "name server name.";
break;
case T_CNAME:
err_msg = ERR_MSG_PREFIX "canonical name.";
break;
case T_MB:
err_msg = ERR_MSG_PREFIX "mailbox name.";
break;
case T_MD:
err_msg = ERR_MSG_PREFIX "mail destination name.";
break;
case T_MF:
err_msg = ERR_MSG_PREFIX "mail forwarder name.";
break;
case T_MG:
err_msg = ERR_MSG_PREFIX "mail group name.";
break;
case T_MR:
err_msg = ERR_MSG_PREFIX "renamed mailbox name.";
break;
case T_PTR:
err_msg = ERR_MSG_PREFIX "PTR name.";
break;
}

SET_MSG_RESULT(result, zbx_strdup(NULL, err_msg));
return SYSINFO_RET_FAIL;
#undef ERR_MSG_PREFIX
}
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);
break;
Expand All @@ -706,7 +746,8 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans

if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* exchange */
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response:"
" cannot expand mail exchange name."));
return SYSINFO_RET_FAIL;
}
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);
Expand All @@ -715,20 +756,22 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans
case T_SOA:
if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* source host */
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response:"
" cannot expand source nameserver name."));
return SYSINFO_RET_FAIL;
}
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* administrator */
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response:"
" cannot expand administrator mailbox name."));
return SYSINFO_RET_FAIL;
}
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

GETLONG(value, msg_ptr); /* serial number */
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %u", (zbx_uint32_t)value);

GETLONG(value, msg_ptr); /* refresh time */
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value);
Expand All @@ -750,7 +793,8 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans
case T_WKS:
if (INT32SZ + 1 > q_len)
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response:"
" malformed WKS resource record."));
return SYSINFO_RET_FAIL;
}

Expand Down Expand Up @@ -816,14 +860,16 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans
case T_MINFO:
if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox responsible for mailing lists */
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response:"
" cannot expand mailbox responsible for mailing lists."));
return SYSINFO_RET_FAIL;
}
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);

if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox for error messages */
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response:"
" cannot expand mailbox for error messages."));
return SYSINFO_RET_FAIL;
}
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);
Expand Down Expand Up @@ -854,7 +900,8 @@ static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_ans

if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* target */
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response."));
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response:"
" cannot expand service target hostname."));
return SYSINFO_RET_FAIL;
}
offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name);
Expand Down
Loading