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:
committed by
Paul Barker
parent
4e6df49262
commit
d29b27fb31
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user