plugins: netlink: fix untrusted loop bound, found by Coverity Scan

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2021-03-07 11:28:39 +01:00
parent ecaf111a4b
commit 6af0446490
+15 -5
View File
@@ -48,7 +48,7 @@ static int nlmsg_validate(struct nlmsghdr *nh, size_t len)
return 0; return 0;
} }
static void nl_route(struct nlmsghdr *nlmsg) static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
{ {
struct rtmsg *r; struct rtmsg *r;
struct rtattr *a; struct rtattr *a;
@@ -63,8 +63,14 @@ static void nl_route(struct nlmsghdr *nlmsg)
r = NLMSG_DATA(nlmsg); r = NLMSG_DATA(nlmsg);
a = RTM_RTA(r); a = RTM_RTA(r);
la = RTM_PAYLOAD(nlmsg); la = RTM_PAYLOAD(nlmsg);
if (la >= len) {
_e("Packet too large!");
return;
}
while (RTA_OK(a, la)) { while (RTA_OK(a, la)) {
void *data = RTA_DATA(a); void *data = RTA_DATA(a);
switch (a->rta_type) { switch (a->rta_type) {
case RTA_GATEWAY: case RTA_GATEWAY:
gw = *((int *)data); gw = *((int *)data);
@@ -105,7 +111,7 @@ static void net_cond_set(char *ifname, char *cond, int set)
cond_clear(msg); cond_clear(msg);
} }
static void nl_link(struct nlmsghdr *nlmsg) static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
{ {
int la; int la;
char ifname[IFNAMSIZ + 1]; char ifname[IFNAMSIZ + 1];
@@ -120,6 +126,10 @@ static void nl_link(struct nlmsghdr *nlmsg)
i = NLMSG_DATA(nlmsg); i = NLMSG_DATA(nlmsg);
a = (struct rtattr *)((char *)i + NLMSG_ALIGN(sizeof(struct ifinfomsg))); a = (struct rtattr *)((char *)i + NLMSG_ALIGN(sizeof(struct ifinfomsg)));
la = NLMSG_PAYLOAD(nlmsg, sizeof(struct ifinfomsg)); la = NLMSG_PAYLOAD(nlmsg, sizeof(struct ifinfomsg));
if (la >= len) {
_e("Packet too large!");
return;
}
while (RTA_OK(a, la)) { while (RTA_OK(a, la)) {
if (a->rta_type == IFLA_IFNAME) { if (a->rta_type == IFLA_IFNAME) {
@@ -164,9 +174,9 @@ static void nl_link(struct nlmsghdr *nlmsg)
static void nl_callback(void *arg, int sd, int events) static void nl_callback(void *arg, int sd, int events)
{ {
ssize_t len;
static char buf[4096]; static char buf[4096];
struct nlmsghdr *nh; struct nlmsghdr *nh;
ssize_t len;
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
len = recv(sd, buf, sizeof(buf), 0); len = recv(sd, buf, sizeof(buf), 0);
@@ -179,9 +189,9 @@ static void nl_callback(void *arg, int sd, int events)
for (nh = (struct nlmsghdr *)buf; !nlmsg_validate(nh, len); nh = NLMSG_NEXT(nh, len)) { for (nh = (struct nlmsghdr *)buf; !nlmsg_validate(nh, len); nh = NLMSG_NEXT(nh, len)) {
//_d("Well formed netlink message received. type %d ...", nh->nlmsg_type); //_d("Well formed netlink message received. type %d ...", nh->nlmsg_type);
if (nh->nlmsg_type == RTM_NEWROUTE || nh->nlmsg_type == RTM_DELROUTE) if (nh->nlmsg_type == RTM_NEWROUTE || nh->nlmsg_type == RTM_DELROUTE)
nl_route(nh); nl_route(nh, len);
else else
nl_link(nh); nl_link(nh, len);
} }
} }