kernel-netlink: Add some safety checks when printing extended error messages
The previous code could potentially cause out-of-bound reads.
Fixes: 7988aea7d8 ("kernel-netlink: Log extended ACK error/warning messages")
This commit is contained in:
@@ -920,8 +920,16 @@ void netlink_log_error(struct nlmsghdr *hdr, const char *prefix)
|
|||||||
struct rtattr *rta;
|
struct rtattr *rta;
|
||||||
size_t offset, rtasize;
|
size_t offset, rtasize;
|
||||||
const char *msg = NULL;
|
const char *msg = NULL;
|
||||||
bool is_error = err->error != 0;
|
bool is_error;
|
||||||
|
|
||||||
|
if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "%s%sreceived truncated netlink error/warning",
|
||||||
|
prefix ? prefix : "", prefix ? ": " : "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_error = err->error != 0;
|
||||||
if (!prefix)
|
if (!prefix)
|
||||||
{
|
{
|
||||||
prefix = is_error ? "received netlink error"
|
prefix = is_error ? "received netlink error"
|
||||||
@@ -935,7 +943,15 @@ void netlink_log_error(struct nlmsghdr *hdr, const char *prefix)
|
|||||||
offset = sizeof(*err);
|
offset = sizeof(*err);
|
||||||
if (!(hdr->nlmsg_flags & NLM_F_CAPPED))
|
if (!(hdr->nlmsg_flags & NLM_F_CAPPED))
|
||||||
{
|
{
|
||||||
|
if (err->msg.nlmsg_len < NLMSG_HDRLEN)
|
||||||
|
{
|
||||||
|
goto log;
|
||||||
|
}
|
||||||
offset += err->msg.nlmsg_len - NLMSG_HDRLEN;
|
offset += err->msg.nlmsg_len - NLMSG_HDRLEN;
|
||||||
|
if (NLMSG_SPACE(offset) > hdr->nlmsg_len)
|
||||||
|
{
|
||||||
|
goto log;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rta = (struct rtattr*)(NLMSG_DATA(hdr) + NLMSG_ALIGN(offset));
|
rta = (struct rtattr*)(NLMSG_DATA(hdr) + NLMSG_ALIGN(offset));
|
||||||
@@ -956,6 +972,7 @@ void netlink_log_error(struct nlmsghdr *hdr, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log:
|
||||||
if (msg && *msg)
|
if (msg && *msg)
|
||||||
{
|
{
|
||||||
if (is_error)
|
if (is_error)
|
||||||
|
|||||||
Reference in New Issue
Block a user