mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-10-01 06:21:56 -09:00
package/dropbear: security bump to version 2026.90
https://github.com/mkj/dropbear/releases/tag/DROPBEAR_2026.90 https://matt.ucc.asn.au/dropbear/CHANGES Fixes CVE-2019-6111 & CVE-2026-35385. Signed-off-by: Bernd Kuhls <bernd@kuhls.net> Signed-off-by: Julien Olivain <ju.o@free.fr> (cherry picked from commit5b136c89ff) [thomas: reverts commit30d1791eb2] Signed-off-by: Thomas Perale <thomas.perale@mind.be>
This commit is contained in:
@@ -1,364 +0,0 @@
|
|||||||
From 143291baca6ebb3407a0c25c85bd53bf041a6ab7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Matt Johnston <matt@ucc.asn.au>
|
|
||||||
Date: Mon, 20 Apr 2026 20:57:11 +0800
|
|
||||||
Subject: [PATCH] scp: more CVE-2019-6111 fix
|
|
||||||
|
|
||||||
Cherrypicked from OpenSSH portable
|
|
||||||
|
|
||||||
commit 3d896c157c722bc47adca51a58dca859225b5874
|
|
||||||
djm Sun Feb 10 11:15:52 2019 +0000
|
|
||||||
|
|
||||||
upstream: when checking that filenames sent by the server side
|
|
||||||
|
|
||||||
match what the client requested, be prepared to handle shell-style brace
|
|
||||||
alternations, e.g. "{foo,bar}".
|
|
||||||
|
|
||||||
"looks good to me" millert@ + in snaps for the last week courtesy
|
|
||||||
deraadt@
|
|
||||||
|
|
||||||
Upstream: https://github.com/mkj/dropbear/commit/143291baca6ebb3407a0c25c85bd53bf041a6ab7.patch
|
|
||||||
CVE: CVE-2019-6111
|
|
||||||
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
|
|
||||||
---
|
|
||||||
src/scp.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++---
|
|
||||||
1 file changed, 269 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/scp.c b/src/scp.c
|
|
||||||
index bf98986c..d151587c 100644
|
|
||||||
--- a/src/scp.c
|
|
||||||
+++ b/src/scp.c
|
|
||||||
@@ -74,7 +74,6 @@
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
-/*RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");*/
|
|
||||||
|
|
||||||
#include <fnmatch.h>
|
|
||||||
|
|
||||||
@@ -600,6 +599,253 @@ tolocal(int argc, char **argv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Appends a string to an array; returns 0 on success, -1 on alloc failure */
|
|
||||||
+static int
|
|
||||||
+append(char *cp, char ***ap, size_t *np)
|
|
||||||
+{
|
|
||||||
+ char **tmp;
|
|
||||||
+
|
|
||||||
+ if ((tmp = reallocarray(*ap, *np + 1, sizeof(*tmp))) == NULL)
|
|
||||||
+ return -1;
|
|
||||||
+ tmp[(*np)] = cp;
|
|
||||||
+ (*np)++;
|
|
||||||
+ *ap = tmp;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Finds the start and end of the first brace pair in the pattern.
|
|
||||||
+ * returns 0 on success or -1 for invalid patterns.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+find_brace(const char *pattern, int *startp, int *endp)
|
|
||||||
+{
|
|
||||||
+ int i;
|
|
||||||
+ int in_bracket, brace_level;
|
|
||||||
+
|
|
||||||
+ *startp = *endp = -1;
|
|
||||||
+ in_bracket = brace_level = 0;
|
|
||||||
+ for (i = 0; i < INT_MAX && *endp < 0 && pattern[i] != '\0'; i++) {
|
|
||||||
+ switch (pattern[i]) {
|
|
||||||
+ case '\\':
|
|
||||||
+ /* skip next character */
|
|
||||||
+ if (pattern[i + 1] != '\0')
|
|
||||||
+ i++;
|
|
||||||
+ break;
|
|
||||||
+ case '[':
|
|
||||||
+ in_bracket = 1;
|
|
||||||
+ break;
|
|
||||||
+ case ']':
|
|
||||||
+ in_bracket = 0;
|
|
||||||
+ break;
|
|
||||||
+ case '{':
|
|
||||||
+ if (in_bracket)
|
|
||||||
+ break;
|
|
||||||
+ if (pattern[i + 1] == '}') {
|
|
||||||
+ /* Protect a single {}, for find(1), like csh */
|
|
||||||
+ i++; /* skip */
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (*startp == -1)
|
|
||||||
+ *startp = i;
|
|
||||||
+ brace_level++;
|
|
||||||
+ break;
|
|
||||||
+ case '}':
|
|
||||||
+ if (in_bracket)
|
|
||||||
+ break;
|
|
||||||
+ if (*startp < 0) {
|
|
||||||
+ /* Unbalanced brace */
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ if (--brace_level <= 0)
|
|
||||||
+ *endp = i;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ /* unbalanced brackets/braces */
|
|
||||||
+ if (*endp < 0 && (*startp >= 0 || in_bracket))
|
|
||||||
+ return -1;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Assembles and records a successfully-expanded pattern, returns -1 on
|
|
||||||
+ * alloc failure.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+emit_expansion(const char *pattern, int brace_start, int brace_end,
|
|
||||||
+ int sel_start, int sel_end, char ***patternsp, size_t *npatternsp)
|
|
||||||
+{
|
|
||||||
+ char *cp;
|
|
||||||
+ int o = 0, tail_len = strlen(pattern + brace_end + 1);
|
|
||||||
+
|
|
||||||
+ if ((cp = malloc(brace_start + (sel_end - sel_start) +
|
|
||||||
+ tail_len + 1)) == NULL)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ /* Pattern before initial brace */
|
|
||||||
+ if (brace_start > 0) {
|
|
||||||
+ memcpy(cp, pattern, brace_start);
|
|
||||||
+ o = brace_start;
|
|
||||||
+ }
|
|
||||||
+ /* Current braced selection */
|
|
||||||
+ if (sel_end - sel_start > 0) {
|
|
||||||
+ memcpy(cp + o, pattern + sel_start,
|
|
||||||
+ sel_end - sel_start);
|
|
||||||
+ o += sel_end - sel_start;
|
|
||||||
+ }
|
|
||||||
+ /* Remainder of pattern after closing brace */
|
|
||||||
+ if (tail_len > 0) {
|
|
||||||
+ memcpy(cp + o, pattern + brace_end + 1, tail_len);
|
|
||||||
+ o += tail_len;
|
|
||||||
+ }
|
|
||||||
+ cp[o] = '\0';
|
|
||||||
+ if (append(cp, patternsp, npatternsp) != 0) {
|
|
||||||
+ free(cp);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Expand the first encountered brace in pattern, appending the expanded
|
|
||||||
+ * patterns it yielded to the *patternsp array.
|
|
||||||
+ *
|
|
||||||
+ * Returns 0 on success or -1 on allocation failure.
|
|
||||||
+ *
|
|
||||||
+ * Signals whether expansion was performed via *expanded and whether
|
|
||||||
+ * pattern was invalid via *invalid.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp,
|
|
||||||
+ int *expanded, int *invalid)
|
|
||||||
+{
|
|
||||||
+ int i;
|
|
||||||
+ int in_bracket, brace_start, brace_end, brace_level;
|
|
||||||
+ int sel_start, sel_end;
|
|
||||||
+
|
|
||||||
+ *invalid = *expanded = 0;
|
|
||||||
+
|
|
||||||
+ if (find_brace(pattern, &brace_start, &brace_end) != 0) {
|
|
||||||
+ *invalid = 1;
|
|
||||||
+ return 0;
|
|
||||||
+ } else if (brace_start == -1)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ in_bracket = brace_level = 0;
|
|
||||||
+ for (i = sel_start = brace_start + 1; i < brace_end; i++) {
|
|
||||||
+ switch (pattern[i]) {
|
|
||||||
+ case '{':
|
|
||||||
+ if (in_bracket)
|
|
||||||
+ break;
|
|
||||||
+ brace_level++;
|
|
||||||
+ break;
|
|
||||||
+ case '}':
|
|
||||||
+ if (in_bracket)
|
|
||||||
+ break;
|
|
||||||
+ brace_level--;
|
|
||||||
+ break;
|
|
||||||
+ case '[':
|
|
||||||
+ in_bracket = 1;
|
|
||||||
+ break;
|
|
||||||
+ case ']':
|
|
||||||
+ in_bracket = 0;
|
|
||||||
+ break;
|
|
||||||
+ case '\\':
|
|
||||||
+ if (i < brace_end - 1)
|
|
||||||
+ i++; /* skip */
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (pattern[i] == ',' || i == brace_end - 1) {
|
|
||||||
+ if (in_bracket || brace_level > 0)
|
|
||||||
+ continue;
|
|
||||||
+ /* End of a selection, emit an expanded pattern */
|
|
||||||
+
|
|
||||||
+ /* Adjust end index for last selection */
|
|
||||||
+ sel_end = (i == brace_end - 1) ? brace_end : i;
|
|
||||||
+ if (emit_expansion(pattern, brace_start, brace_end,
|
|
||||||
+ sel_start, sel_end, patternsp, npatternsp) != 0)
|
|
||||||
+ return -1;
|
|
||||||
+ /* move on to the next selection */
|
|
||||||
+ sel_start = i + 1;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (in_bracket || brace_level > 0) {
|
|
||||||
+ *invalid = 1;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ /* success */
|
|
||||||
+ *expanded = 1;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* Expand braces from pattern. Returns 0 on success, -1 on failure */
|
|
||||||
+static int
|
|
||||||
+brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp)
|
|
||||||
+{
|
|
||||||
+ char *cp, *cp2, **active = NULL, **done = NULL;
|
|
||||||
+ size_t i, nactive = 0, ndone = 0;
|
|
||||||
+ int ret = -1, invalid = 0, expanded = 0;
|
|
||||||
+
|
|
||||||
+ *patternsp = NULL;
|
|
||||||
+ *npatternsp = 0;
|
|
||||||
+
|
|
||||||
+ /* Start the worklist with the original pattern */
|
|
||||||
+ if ((cp = strdup(pattern)) == NULL)
|
|
||||||
+ return -1;
|
|
||||||
+ if (append(cp, &active, &nactive) != 0) {
|
|
||||||
+ free(cp);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ while (nactive > 0) {
|
|
||||||
+ cp = active[nactive - 1];
|
|
||||||
+ nactive--;
|
|
||||||
+ if (brace_expand_one(cp, &active, &nactive,
|
|
||||||
+ &expanded, &invalid) == -1) {
|
|
||||||
+ free(cp);
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ if (invalid)
|
|
||||||
+ fatal("%s: invalid brace pattern \"%s\"", __func__, cp);
|
|
||||||
+ if (expanded) {
|
|
||||||
+ /*
|
|
||||||
+ * Current entry expanded to new entries on the
|
|
||||||
+ * active list; discard the progenitor pattern.
|
|
||||||
+ */
|
|
||||||
+ free(cp);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ /*
|
|
||||||
+ * Pattern did not expand; append the finename component to
|
|
||||||
+ * the completed list
|
|
||||||
+ */
|
|
||||||
+ if ((cp2 = strrchr(cp, '/')) != NULL)
|
|
||||||
+ *cp2++ = '\0';
|
|
||||||
+ else
|
|
||||||
+ cp2 = cp;
|
|
||||||
+ if (append(xstrdup(cp2), &done, &ndone) != 0) {
|
|
||||||
+ free(cp);
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+ free(cp);
|
|
||||||
+ }
|
|
||||||
+ /* success */
|
|
||||||
+ *patternsp = done;
|
|
||||||
+ *npatternsp = ndone;
|
|
||||||
+ done = NULL;
|
|
||||||
+ ndone = 0;
|
|
||||||
+ ret = 0;
|
|
||||||
+ fail:
|
|
||||||
+ for (i = 0; i < nactive; i++)
|
|
||||||
+ free(active[i]);
|
|
||||||
+ free(active);
|
|
||||||
+ for (i = 0; i < ndone; i++)
|
|
||||||
+ free(done[i]);
|
|
||||||
+ free(done);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
source(int argc, char **argv)
|
|
||||||
{
|
|
||||||
@@ -841,7 +1087,8 @@ sink(int argc, char **argv, const char *src)
|
|
||||||
off_t size, statbytes;
|
|
||||||
int setimes, targisdir, wrerrno = 0;
|
|
||||||
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
|
|
||||||
- char *src_copy = NULL, *restrict_pattern = NULL;
|
|
||||||
+ char **patterns = NULL;
|
|
||||||
+ size_t n, npatterns = 0;
|
|
||||||
struct timeval tv[2];
|
|
||||||
|
|
||||||
#define atime tv[0]
|
|
||||||
@@ -868,16 +1115,13 @@ sink(int argc, char **argv, const char *src)
|
|
||||||
* Prepare to try to restrict incoming filenames to match
|
|
||||||
* the requested destination file glob.
|
|
||||||
*/
|
|
||||||
- if ((src_copy = strdup(src)) == NULL)
|
|
||||||
- fatal("strdup failed");
|
|
||||||
- if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) {
|
|
||||||
- *restrict_pattern++ = '\0';
|
|
||||||
- }
|
|
||||||
+ if (brace_expand(src, &patterns, &npatterns) != 0)
|
|
||||||
+ fatal("%s: could not expand pattern", __func__);
|
|
||||||
}
|
|
||||||
for (first = 1;; first = 0) {
|
|
||||||
cp = buf;
|
|
||||||
if (atomicio(read, remin, cp, 1) != 1)
|
|
||||||
- return;
|
|
||||||
+ goto done;
|
|
||||||
if (*cp++ == '\n')
|
|
||||||
SCREWUP("unexpected <newline>");
|
|
||||||
do {
|
|
||||||
@@ -900,7 +1144,7 @@ sink(int argc, char **argv, const char *src)
|
|
||||||
}
|
|
||||||
if (buf[0] == 'E') {
|
|
||||||
(void) atomicio(vwrite, remout, "", 1);
|
|
||||||
- return;
|
|
||||||
+ goto done;
|
|
||||||
}
|
|
||||||
if (ch == '\n')
|
|
||||||
*--cp = 0;
|
|
||||||
@@ -956,9 +1200,14 @@ sink(int argc, char **argv, const char *src)
|
|
||||||
run_err("error: unexpected filename: %s", cp);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
- if (restrict_pattern != NULL &&
|
|
||||||
- fnmatch(restrict_pattern, cp, 0) != 0)
|
|
||||||
- SCREWUP("filename does not match request");
|
|
||||||
+ if (npatterns > 0) {
|
|
||||||
+ for (n = 0; n < npatterns; n++) {
|
|
||||||
+ if (fnmatch(patterns[n], cp, 0) == 0)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (n >= npatterns)
|
|
||||||
+ SCREWUP("filename does not match request");
|
|
||||||
+ }
|
|
||||||
if (targisdir) {
|
|
||||||
static char *namebuf = NULL;
|
|
||||||
static size_t cursize = 0;
|
|
||||||
@@ -1123,7 +1372,15 @@ bad: run_err("%s: %s", np, strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+done:
|
|
||||||
+ for (n = 0; n < npatterns; n++)
|
|
||||||
+ free(patterns[n]);
|
|
||||||
+ free(patterns);
|
|
||||||
+ return;
|
|
||||||
screwup:
|
|
||||||
+ for (n = 0; n < npatterns; n++)
|
|
||||||
+ free(patterns[n]);
|
|
||||||
+ free(patterns);
|
|
||||||
run_err("protocol error: %s", why);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
From 443ccc1fd1b9a4e3747f6b5cd644b7af49064308 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Matt Johnston <matt@ucc.asn.au>
|
|
||||||
Date: Sat, 2 May 2026 08:17:25 +0800
|
|
||||||
Subject: [PATCH] scp: clear setuid/setgid bits on received files
|
|
||||||
|
|
||||||
From openssh-portable 487e8ac146f7d6616f65c125d5edb210519b833a
|
|
||||||
Tracked as CVE-2026-35385
|
|
||||||
|
|
||||||
upstream: when downloading files as root in legacy (-O) mode and
|
|
||||||
|
|
||||||
without the -p (preserve modes) flag set, clear setuid/setgid bits from
|
|
||||||
downloaded files as one might expect.
|
|
||||||
|
|
||||||
AFAIK this bug dates back to the original Berkeley rcp program.
|
|
||||||
|
|
||||||
Reported by Christos Papakonstantinou of Cantina and Spearbit.
|
|
||||||
|
|
||||||
Upstream: https://github.com/mkj/dropbear/commit/443ccc1fd1b9a4e3747f6b5cd644b7af49064308.patch
|
|
||||||
CVE: CVE-2026-35385
|
|
||||||
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
|
|
||||||
---
|
|
||||||
src/scp.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/scp.c b/src/scp.c
|
|
||||||
index 09297a5b..79b0a12d 100644
|
|
||||||
--- a/src/scp.c
|
|
||||||
+++ b/src/scp.c
|
|
||||||
@@ -1106,8 +1106,10 @@ sink(int argc, char **argv, const char *src)
|
|
||||||
|
|
||||||
setimes = targisdir = 0;
|
|
||||||
mask = umask(0);
|
|
||||||
- if (!pflag)
|
|
||||||
+ if (!pflag) {
|
|
||||||
+ mask |= 07000;
|
|
||||||
(void) umask(mask);
|
|
||||||
+ }
|
|
||||||
if (argc != 1) {
|
|
||||||
run_err("ambiguous target");
|
|
||||||
exit(1);
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# From https://matt.ucc.asn.au/dropbear/releases/SHA256SUM.asc
|
# From https://matt.ucc.asn.au/dropbear/releases/SHA256SUM.asc
|
||||||
sha256 0d1f7ca711cfc336dc8a85e672cab9cfd8223a02fe2da0a4a7aeb58c9e113634 dropbear-2025.89.tar.bz2
|
sha256 16be820347723271b0fea6049ffeed6d6680d7429c65406d8af37776393a0250 dropbear-2026.90.tar.bz2
|
||||||
|
|
||||||
# License file, locally computed
|
# License file, locally computed
|
||||||
sha256 a99ce657d790b761c132ee7e0de18edb437ae6361e536d991c6a12f36e770445 LICENSE
|
sha256 a99ce657d790b761c132ee7e0de18edb437ae6361e536d991c6a12f36e770445 LICENSE
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
DROPBEAR_VERSION = 2025.89
|
DROPBEAR_VERSION = 2026.90
|
||||||
DROPBEAR_SITE = https://matt.ucc.asn.au/dropbear/releases
|
DROPBEAR_SITE = https://matt.ucc.asn.au/dropbear/releases
|
||||||
DROPBEAR_SOURCE = dropbear-$(DROPBEAR_VERSION).tar.bz2
|
DROPBEAR_SOURCE = dropbear-$(DROPBEAR_VERSION).tar.bz2
|
||||||
DROPBEAR_LICENSE = MIT, BSD-2-Clause, Public domain
|
DROPBEAR_LICENSE = MIT, BSD-2-Clause, Public domain
|
||||||
@@ -14,12 +14,6 @@ DROPBEAR_PROGRAMS = dropbear $(DROPBEAR_TARGET_BINS)
|
|||||||
DROPBEAR_CPE_ID_VENDOR = dropbear_ssh_project
|
DROPBEAR_CPE_ID_VENDOR = dropbear_ssh_project
|
||||||
DROPBEAR_CPE_ID_PRODUCT = dropbear_ssh
|
DROPBEAR_CPE_ID_PRODUCT = dropbear_ssh
|
||||||
|
|
||||||
# 0001-CVE-2019-6111.patch
|
|
||||||
DROPBEAR_IGNORE_CVES += CVE-2019-6111
|
|
||||||
|
|
||||||
# 0002-CVE-2026-35385.patch
|
|
||||||
DROPBEAR_IGNORE_CVES += CVE-2026-35385
|
|
||||||
|
|
||||||
# Disable hardening flags added by dropbear configure.ac, and let
|
# Disable hardening flags added by dropbear configure.ac, and let
|
||||||
# Buildroot add them when the relevant options are enabled. This
|
# Buildroot add them when the relevant options are enabled. This
|
||||||
# prevents dropbear from using SSP support when not available.
|
# prevents dropbear from using SSP support when not available.
|
||||||
|
|||||||
Reference in New Issue
Block a user