--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: trixie
User: [email protected]
Usertags: pu
X-Debbugs-Cc: [email protected], [email protected],
[email protected]
Control: affects -1 + src:lxc
[ Reason ]
The release of LXC 7.0 included a fix for the low severity CVE-2026-
39402. After discussion with the Security Team, this vulnerability
won't receive its own DSA, but will be addressed via the upcoming point
release.
[ Impact ]
LXC in trixie is currently vulnerable to CVE-2026-39402.
[ Tests ]
Upstream did add a test in the 7.0 release, but I haven't included it
in the cherry-pick because the packaging of lxc in trixie won't ever
actually run it.
[ Risks ]
Minor/none -- one targeted fix cherry-picked from the upstream git
repo.
[ Checklist ]
[*] *all* changes are documented in the d/changelog
[*] I reviewed all changes and I approve them
[*] attach debdiff against the package in (old)stable
[*] the issue is verified as fixed in unstable
[ Changes ]
One patch as outlined above.
[ Other info ]
The source debdiff is attached.
diff -Nru lxc-6.0.4/debian/changelog lxc-6.0.4/debian/changelog
--- lxc-6.0.4/debian/changelog 2026-03-02 19:05:00.000000000 +0000
+++ lxc-6.0.4/debian/changelog 2026-04-30 18:57:04.000000000 +0000
@@ -1,3 +1,9 @@
+lxc (1:6.0.4-4+deb13u3) trixie; urgency=medium
+
+ * Cherry-pick upstream fix for CVE-2026-39402
+
+ -- Mathias Gibbens <[email protected]> Thu, 30 Apr 2026 18:57:04 +0000
+
lxc (1:6.0.4-4+deb13u2) trixie; urgency=medium
* Cherry-pick upstream fix for data corruption during heavy IO on PTS
diff -Nru lxc-6.0.4/debian/patches/0106-cherry-pick-CVE-2026-39402.patch lxc-6.0.4/debian/patches/0106-cherry-pick-CVE-2026-39402.patch
--- lxc-6.0.4/debian/patches/0106-cherry-pick-CVE-2026-39402.patch 1970-01-01 00:00:00.000000000 +0000
+++ lxc-6.0.4/debian/patches/0106-cherry-pick-CVE-2026-39402.patch 2026-04-30 18:56:25.000000000 +0000
@@ -0,0 +1,168 @@
+From 9a68e2e134a1886aaa084129a3e065cee2d40ed9 Mon Sep 17 00:00:00 2001
+From: "Serge E. Hallyn" <[email protected]>
+Date: Mon, 20 Apr 2026 23:07:47 -0500
+Subject: [PATCH] lxc-user-nic: clarify and fix
+
+Some variable names were a bit confusing in find_line and cull_entries.
+Rename and document, and fix the flows using these.
+
+It's possible that a more maintainable approach, long term, would be
+to break these up differently: have one function create a neat
+in memory data structure representing the files, and have the paths
+currently using find_line and cull_entries peek into the data structures.
+But i think this is pretty clear.
+
+This fixes CVE-2026-39402
+
+Signed-off-by: Serge E. Hallyn <[email protected]>
+Reviewed-by: Alexander Mikhalitsyn <[email protected]>
+---
+ src/lxc/cmd/lxc_user_nic.c | 75 +++++++++++++++++++++++++++++---------
+ 1 file changed, 57 insertions(+), 18 deletions(-)
+
+diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c
+index 98aedf8216..83fd84a185 100644
+--- a/src/lxc/cmd/lxc_user_nic.c
++++ b/src/lxc/cmd/lxc_user_nic.c
+@@ -374,19 +374,58 @@ static char *get_eow(char *s, char *e)
+ return s;
+ }
+
++static bool same_word(const char *start, const char *end, const char *word)
++{
++ size_t wordlen = strlen(word);
++ size_t buflen = end - start;
++
++ if (wordlen != buflen)
++ return false;
++ if (strncmp(start, word, wordlen) == 0)
++ return true;
++ return false;
++}
++
++/*
++ * in:
++ * @buf_start and @buf_end point to the buffer to be read.
++ *
++ * @owner_name is the name of the user who should own the link.
++ *
++ * @net_type is type of connection, e.g. veth
++ *
++ * @net_link is the name of the bridge, e.g. lxcbr0, on which the
++ * device should live.
++ *
++ * @net_dev is the name of the device itself in the host netns.
++ *
++ * out:
++ * @is_owner is set to true if the current line is owned by @name.
++
++ * @nic_found is set to true if the line is specifically for the passed-in
++ * @net_dev, and it is on the right @net_link and of the right @net_type.
++ *
++ * @exists is set to false if the nic in this line no longer exists. This is
++ * used by cull_entries(): if we set it to false, then this line will be
++ * removed from the LXC_USERNIC_DB (e.g. /var/run/lxc/nics).
++ */
+ static char *find_line(char *buf_start, char *buf_end, char *name,
+ char *net_type, char *net_link, char *net_dev,
+- bool *owner, bool *found, bool *keep)
++ bool *is_owner, bool *nic_found, bool *exists)
+ {
+ char *end_of_line, *end_of_word, *line;
++ bool right_net_type, right_bridge, right_link_name;;
+
+ while (buf_start < buf_end) {
+ size_t len;
+ char netdev_name[IFNAMSIZ];
+
+- *found = false;
+- *keep = true;
+- *owner = false;
++ *nic_found = false;
++ *exists = true;
++ *is_owner = false;
++ right_net_type = false;
++ right_bridge = false;
++ right_link_name = false;
+
+ end_of_line = get_eol(buf_start, buf_end);
+ if (end_of_line >= buf_end)
+@@ -405,11 +444,8 @@ static char *find_line(char *buf_start, char *buf_end, char *name,
+ if (!end_of_word)
+ return NULL;
+
+- if (strncmp(buf_start, name, strlen(name)))
+- *found = false;
+- else
+- if (strlen(name) == (size_t)(end_of_word - buf_start))
+- *owner = true;
++ if (same_word(buf_start, end_of_word, name))
++ *is_owner = true;
+
+ buf_start = end_of_word + 1;
+ while ((buf_start < buf_end) && isblank(*buf_start))
+@@ -421,8 +457,8 @@ static char *find_line(char *buf_start, char *buf_end, char *name,
+ if (!end_of_word)
+ return NULL;
+
+- if (strncmp(buf_start, net_type, strlen(net_type)))
+- *found = false;
++ if (same_word(buf_start, end_of_word, net_type))
++ right_net_type = true;
+
+ buf_start = end_of_word + 1;
+ while ((buf_start < buf_end) && isblank(*buf_start))
+@@ -434,8 +470,8 @@ static char *find_line(char *buf_start, char *buf_end, char *name,
+ if (!end_of_word)
+ return NULL;
+
+- if (strncmp(buf_start, net_link, strlen(net_link)))
+- *found = false;
++ if (same_word(buf_start, end_of_word, net_link))
++ right_bridge = true;
+
+ buf_start = end_of_word + 1;
+ while ((buf_start < buf_end) && isblank(*buf_start))
+@@ -454,10 +490,13 @@ static char *find_line(char *buf_start, char *buf_end, char *name,
+
+ memcpy(netdev_name, buf_start, len);
+ netdev_name[len] = '\0';
+- *keep = lxc_nic_exists(netdev_name);
++ *exists = lxc_nic_exists(netdev_name);
+
+ if (net_dev && !strcmp(netdev_name, net_dev))
+- *found = true;
++ right_link_name = true;
++
++ if (right_net_type && right_bridge && right_link_name)
++ *nic_found = true;
+
+ return line;
+
+@@ -587,7 +626,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
+ size_t length = 0;
+ int ret;
+ char *buf_end, *buf_start;
+- bool found, keep;
++ bool nic_found, is_owner, keep;
+
+ ret = fd_to_buf(fd, &buf, &length);
+ if (ret < 0) {
+@@ -603,7 +642,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
+ buf_start = buf;
+ buf_end = buf + length;
+ while ((buf_start = find_line(buf_start, buf_end, name, net_type,
+- net_link, net_dev, &(bool){true}, &found,
++ net_link, net_dev, &is_owner, &nic_found,
+ &keep))) {
+ struct entry_line *newe;
+
+@@ -611,7 +650,7 @@ static bool cull_entries(int fd, char *name, char *net_type, char *net_link,
+ if (!newe)
+ return false;
+
+- if (found)
++ if (nic_found && is_owner)
+ *found_nicname = true;
+
+ entry_lines = newe;
diff -Nru lxc-6.0.4/debian/patches/series lxc-6.0.4/debian/patches/series
--- lxc-6.0.4/debian/patches/series 2026-03-02 19:05:00.000000000 +0000
+++ lxc-6.0.4/debian/patches/series 2026-04-30 18:56:52.000000000 +0000
@@ -8,3 +8,4 @@
0103-cherry-pick-fix-dbus-reboots.patch
0104-Add-lxc-net-as-dependency-in-sysvinit-script.patch
0105-cherry-pick-fix-heavy-io-pts.patch
+0106-cherry-pick-CVE-2026-39402.patch
signature.asc
Description: This is a digitally signed message part
--- End Message ---