diff options
| author | Roy Marples <roy@marples.name> | 2020-05-21 16:53:54 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-05-21 16:53:54 +0100 |
| commit | 22a703a7a3ef6b297371a6b61cffacb5556a33f9 (patch) | |
| tree | f93fc01f43d9da6dca16ddfc58701978a0023797 /src/privsep-inet.c | |
| parent | 4fc992947e26b7662dee02285708a2a5c8514c24 (diff) | |
| download | dhcpcd-22a703a7a3ef6b297371a6b61cffacb5556a33f9.tar.xz | |
privsep: Validate UDP ports
Just like we filter the ioctls.
Diffstat (limited to 'src/privsep-inet.c')
| -rw-r--r-- | src/privsep-inet.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/privsep-inet.c b/src/privsep-inet.c index bc8a3974..c5233024 100644 --- a/src/privsep-inet.c +++ b/src/privsep-inet.c @@ -200,6 +200,25 @@ ps_inet_startcb(void *arg) return ret; } +static bool +ps_inet_udpports(struct msghdr *msg, uint16_t sport, uint16_t dport) +{ + struct udphdr udp; + struct iovec *iov = msg->msg_iov; + + if (msg->msg_iovlen == 0 || iov->iov_len < sizeof(udp)) { + errno = EINVAL; + return false; + } + + memcpy(&udp, iov->iov_base, sizeof(udp)); + if (udp.uh_sport != htons(sport) || udp.uh_dport != htons(dport)) { + errno = EPERM; + return false; + } + return true; +} + static ssize_t ps_inet_sendmsg(struct dhcpcd_ctx *ctx, struct ps_msghdr *psm, struct msghdr *msg) @@ -216,6 +235,8 @@ ps_inet_sendmsg(struct dhcpcd_ctx *ctx, switch (psm->ps_cmd) { #ifdef INET case PS_BOOTP: + if (!ps_inet_udpports(msg, BOOTPC, BOOTPS)) + return -1; s = ctx->udp_wfd; break; #endif @@ -226,6 +247,8 @@ ps_inet_sendmsg(struct dhcpcd_ctx *ctx, #endif #ifdef DHCP6 case PS_DHCP6: + if (!ps_inet_udpports(msg, DHCP6_CLIENT_PORT,DHCP6_SERVER_PORT)) + return -1; s = ctx->dhcp6_wfd; break; #endif |
