1
0
mirror of https://git.yoctoproject.org/poky synced 2026-07-24 06:27:03 +00:00

dhcpcd: patch CVE-2026-56117

Backport patch [1] mentionned in [2]

[1] https://github.com/NetworkConfiguration/dhcpcd/commit/78ea09ed1633a583dbcde6e7bab9df4639ec8a34

[2] https://security-tracker.debian.org/tracker/CVE-2026-56117

(From OE-Core rev: 5c94b031f12c8623dc6eb9e05b87a004826345c1)

Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
Theo Gaige (Schneider Electric)
2026-07-01 17:04:33 +02:00
committed by Paul Barker
parent 4e6df49262
commit d29b27fb31
2 changed files with 168 additions and 0 deletions
@@ -17,6 +17,7 @@ SRC_URI = "git://github.com/NetworkConfiguration/dhcpcd;protocol=https;branch=ma
file://0001-dhcpcd.8-Fix-conflict-error-when-enable-multilib.patch \
file://CVE-2026-56113.patch \
file://CVE-2026-56114.patch \
file://CVE-2026-56117.patch \
"
SRCREV = "1c8ae59836fa87b4c63c598087f0460ec20ed862"
@@ -0,0 +1,167 @@
From 52e0746deeace02b0ea039441d6cdc58f026018d Mon Sep 17 00:00:00 2001
From: Roy Marples <roy@marples.name>
Date: Mon, 22 Jun 2026 23:41:53 +0100
Subject: [PATCH] control: Avoid hangup in the recvdata path
Instead return an error and bubble it up where it can be
hangup / freed more cleanly.
Reported-by: CuB3y0nd <root@cubeyond.net>
(cherry picked from commit 78ea09ed1633a583dbcde6e7bab9df4639ec8a34)
CVE: CVE-2026-56117
Upstream-Status: Backport [https://github.com/NetworkConfiguration/dhcpcd/commit/78ea09ed1633a583dbcde6e7bab9df4639ec8a34]
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
---
src/control.c | 47 ++++++++++++++++++++++++-------------------
src/control.h | 2 +-
src/privsep-control.c | 7 ++++++-
3 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/src/control.c b/src/control.c
index 17fd13aa..20480f69 100644
--- a/src/control.c
+++ b/src/control.c
@@ -115,10 +115,8 @@ control_handle_read(struct fd_list *fd)
bytes = read(fd->fd, buffer, sizeof(buffer) - 1);
if (bytes == -1)
logerr(__func__);
- if (bytes == -1 || bytes == 0) {
- control_hangup(fd);
- return -1;
- }
+ if (bytes == -1 || bytes == 0)
+ return (int)bytes;
#ifdef PRIVSEP
if (IN_PRIVSEP(fd->ctx)) {
@@ -134,15 +132,13 @@ control_handle_read(struct fd_list *fd)
if (err == 1 &&
ps_ctl_sendargs(fd, buffer, (size_t)bytes) == -1) {
logerr(__func__);
- control_free(fd);
return -1;
}
- return 0;
+ return 1;
}
#endif
- control_recvdata(fd, buffer, (size_t)bytes);
- return 0;
+ return control_recvdata(fd, buffer, (size_t)bytes);
}
static int
@@ -205,23 +201,31 @@ static void
control_handle_data(void *arg, unsigned short events)
{
struct fd_list *fd = arg;
+ int err;
if (!(events & (ELE_READ | ELE_WRITE | ELE_HANGUP)))
logerrx("%s: unexpected event 0x%04x", __func__, events);
if (events & ELE_WRITE && !(events & ELE_HANGUP)) {
- if (control_handle_write(fd) == -1)
- return;
+ err = control_handle_write(fd);
+ if (err == -1)
+ goto hangup;
}
if (events & ELE_READ) {
- if (control_handle_read(fd) == -1)
- return;
+ err = control_handle_read(fd);
+ if (err == -1 || err == 0)
+ goto hangup;
}
if (events & ELE_HANGUP)
- control_hangup(fd);
+ goto hangup;
+
+ return;
+
+hangup:
+ control_hangup(fd);
}
-void
+int
control_recvdata(struct fd_list *fd, char *data, size_t len)
{
char *p = data, *e;
@@ -243,12 +247,13 @@ control_recvdata(struct fd_list *fd, char *data, size_t len)
if (e == NULL) {
errno = EINVAL;
logerrx("%s: no terminator", __func__);
- return;
+ return -1;
}
- if ((size_t)argc >= sizeof(argvp) / sizeof(argvp[0])) {
+ if ((size_t)argc + 1 >=
+ sizeof(argvp) / sizeof(argvp[0])) {
errno = ENOBUFS;
logerrx("%s: no arg buffer", __func__);
- return;
+ return -1;
}
*ap++ = p;
argc++;
@@ -268,12 +273,12 @@ control_recvdata(struct fd_list *fd, char *data, size_t len)
*ap = NULL;
if (dhcpcd_handleargs(fd->ctx, fd, argc, argvp) == -1) {
logerr(__func__);
- if (errno != EINTR && errno != EAGAIN) {
- control_free(fd);
- return;
- }
+ if (errno != EINTR && errno != EAGAIN)
+ return -1;
}
}
+
+ return 1;
}
struct fd_list *
diff --git a/src/control.h b/src/control.h
index f5e2bc7e..c5511dd7 100644
--- a/src/control.h
+++ b/src/control.h
@@ -75,5 +75,5 @@ struct fd_list *control_new(struct dhcpcd_ctx *, int, unsigned int);
void control_free(struct fd_list *);
void control_delete(struct fd_list *);
int control_queue(struct fd_list *, void *, size_t);
-void control_recvdata(struct fd_list *fd, char *, size_t);
+int control_recvdata(struct fd_list *fd, char *, size_t);
#endif
diff --git a/src/privsep-control.c b/src/privsep-control.c
index 40bfb164..954126c0 100644
--- a/src/privsep-control.c
+++ b/src/privsep-control.c
@@ -108,6 +108,7 @@ ps_ctl_dispatch(void *arg, struct ps_msghdr *psm, struct msghdr *msg)
struct iovec *iov = msg->msg_iov;
struct fd_list *fd;
unsigned int fd_flags = FD_SENDLEN;
+ int err;
switch (psm->ps_flags) {
case PS_CTL_PRIV:
@@ -131,7 +132,11 @@ ps_ctl_dispatch(void *arg, struct ps_msghdr *psm, struct msghdr *msg)
if (fd == NULL)
return -1;
ctx->ps_control_client = fd;
- control_recvdata(fd, iov->iov_base, iov->iov_len);
+ err = control_recvdata(fd, iov->iov_base, iov->iov_len);
+ if (err == -1 || err == 0) {
+ control_free(fd);
+ ctx->ps_control_client = NULL;
+ }
break;
case PS_CTL_EOF:
ctx->ps_control_client = NULL;
--
2.43.0