diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-08-08 17:45:35 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-08-08 17:45:35 +0300 |
| commit | af009c87b41ea1bb594d68e53d46ca050057e2db (patch) | |
| tree | e3098d9b83c0b904bc585c664b3b857f653b04ea /accel-pppd/ctrl/ipoe | |
| parent | 59124bbc26bf0211723b3eb5b5186d3dc7b72b0c (diff) | |
| download | accel-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.c | 20 |
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; |
