summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/ipoe
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-08-08 17:45:35 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-08-08 17:45:35 +0300
commitaf009c87b41ea1bb594d68e53d46ca050057e2db (patch)
treee3098d9b83c0b904bc585c664b3b857f653b04ea /accel-pppd/ctrl/ipoe
parent59124bbc26bf0211723b3eb5b5186d3dc7b72b0c (diff)
downloadaccel-ppp-af009c87b41ea1bb594d68e53d46ca050057e2db.tar.gz
accel-ppp-af009c87b41ea1bb594d68e53d46ca050057e2db.zip
ipoe: zero generic netlink requests before filling them in
The request buffers are plain stack variables and only the nlmsghdr fields and genlmsghdr.cmd were ever assigned, so genlmsghdr.version and genlmsghdr.reserved reached the kernel holding whatever happened to be on the stack. Since 6.1 genetlink validates the reserved header fields of every command whose id is >= genl_family.resv_start_op, and ipoe sets that field to CTRL_CMD_GETPOLICY + 1, i.e. 11. IPOE_CMD_DEL_NET is 11, so ipoe_nl_del_net(), which runs on startup and on every config reload, is already rejected with EINVAL whenever that garbage is nonzero, and any command added after it is affected as well.
Diffstat (limited to 'accel-pppd/ctrl/ipoe')
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe_netlink.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
index 7057c91e..94b7f42a 100644
--- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c
+++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
@@ -46,6 +46,8 @@ int ipoe_nl_add_exclude(uint32_t addr, int mask)
return -1;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -82,6 +84,8 @@ void ipoe_nl_del_exclude(uint32_t addr)
return;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -114,6 +118,8 @@ int ipoe_nl_add_net(uint32_t addr, int mask)
return -1;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -150,6 +156,8 @@ void ipoe_nl_del_net(uint32_t addr)
return;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -181,6 +189,8 @@ void ipoe_nl_add_interface(int ifindex, uint8_t mode)
return;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -213,6 +223,8 @@ void ipoe_nl_del_interface(int ifindex)
return;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -253,6 +265,8 @@ int ipoe_nl_create()
return -1;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -317,6 +331,8 @@ int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, uint32_t gw,
return -1;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -406,6 +422,8 @@ void ipoe_nl_get_sessions(struct list_head *list)
if (rth.fd == -1)
return;
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
@@ -438,6 +456,8 @@ void ipoe_nl_delete(int ifindex)
return;
}
+ memset(&req, 0, sizeof(req));
+
nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;