From f98bb1ffe5327d7309f11a3647efd8116d637b33 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Mon, 20 Jun 2022 10:37:15 +0300 Subject: [PATCH] dropbear: cherry-pick upstream commit 544f28a0 Resolves #10081 Reported-By: Chen Minqiang Signed-off-by: Konstantin Demin --- ...01-fix-MAX_UNAUTH_CLIENTS-regression.patch | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch diff --git a/package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch b/package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch new file mode 100644 index 0000000000..e0dca544ec --- /dev/null +++ b/package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch @@ -0,0 +1,134 @@ +From: Matt Johnston +Date: Wed, 8 Jun 2022 21:26:20 +0800 +Subject: Fix MAX_UNAUTH_CLIENTS regression + +Since re-exec change in 2022.82 Dropbear count +treat authenticated sessions towards the unauthenticated +session limit. This is fixed by passing the childpipe FD +through to the re-execed process. +--- + runopts.h | 5 +++-- + svr-main.c | 21 +++++++++++---------- + svr-runopts.c | 15 ++++++++++++--- + 3 files changed, 26 insertions(+), 15 deletions(-) + +--- a/runopts.h ++++ b/runopts.h +@@ -79,8 +79,9 @@ typedef struct svr_runopts { + char *addresses[DROPBEAR_MAX_PORTS]; + + int inetdmode; +- /* Hidden "-2" flag indicates it's re-executing itself */ +- int reexec_child; ++ /* Hidden "-2 childpipe_fd" flag indicates it's re-executing itself, ++ stores the childpipe preauth file descriptor. Set to -1 otherwise. */ ++ int reexec_childpipe; + + /* Flags indicating whether to use ipv4 and ipv6 */ + /* not used yet +--- a/svr-main.c ++++ b/svr-main.c +@@ -71,7 +71,7 @@ int main(int argc, char ** argv) + #endif + + #if DROPBEAR_DO_REEXEC +- if (svr_opts.reexec_child) { ++ if (svr_opts.reexec_childpipe >= 0) { + #ifdef PR_SET_NAME + /* Fix the "Name:" in /proc/pid/status, otherwise it's + a FD number from fexecve. +@@ -102,7 +102,7 @@ static void main_inetd() { + + seedrandom(); + +- if (!svr_opts.reexec_child) { ++ if (svr_opts.reexec_childpipe < 0) { + /* In case our inetd was lax in logging source addresses */ + get_socket_address(0, NULL, NULL, &host, &port, 0); + dropbear_log(LOG_INFO, "Child connection from %s:%s", host, port); +@@ -115,10 +115,8 @@ static void main_inetd() { + setsid(); + } + +- /* Start service program +- * -1 is a dummy childpipe, just something we can close() without +- * mattering. */ +- svr_session(0, -1); ++ /* -1 for childpipe in the inetd case is discarded */ ++ svr_session(0, svr_opts.reexec_childpipe); + + /* notreached */ + } +@@ -347,9 +345,10 @@ static void main_noinetd(int argc, char + + if (execfd >= 0) { + #if DROPBEAR_DO_REEXEC +- /* Add "-2" to the args and re-execute ourself. */ +- char **new_argv = m_malloc(sizeof(char*) * (argc+3)); +- int pos0 = 0, new_argc = argc+1; ++ /* Add "-2 childpipe[1]" to the args and re-execute ourself. */ ++ char **new_argv = m_malloc(sizeof(char*) * (argc+4)); ++ char buf[10]; ++ int pos0 = 0, new_argc = argc+2; + + /* We need to specially handle "dropbearmulti dropbear". */ + if (multipath) { +@@ -359,7 +358,9 @@ static void main_noinetd(int argc, char + } + + memcpy(&new_argv[pos0], argv, sizeof(char*) * argc); +- new_argv[new_argc-1] = "-2"; ++ new_argv[new_argc-2] = "-2"; ++ snprintf(buf, sizeof(buf), "%d", childpipe[1]); ++ new_argv[new_argc-1] = buf; + new_argv[new_argc] = NULL; + + if ((dup2(childsock, STDIN_FILENO) < 0)) { +--- a/svr-runopts.c ++++ b/svr-runopts.c +@@ -138,6 +138,7 @@ void svr_getopts(int argc, char ** argv) + char* keepalive_arg = NULL; + char* idle_timeout_arg = NULL; + char* maxauthtries_arg = NULL; ++ char* reexec_fd_arg = NULL; + char* keyfile = NULL; + char c; + #if DROPBEAR_PLUGIN +@@ -175,6 +176,7 @@ void svr_getopts(int argc, char ** argv) + svr_opts.pubkey_plugin_options = NULL; + #endif + svr_opts.pass_on_env = 0; ++ svr_opts.reexec_childpipe = -1; + + #ifndef DISABLE_ZLIB + opts.compress_mode = DROPBEAR_COMPRESS_DELAYED; +@@ -250,12 +252,12 @@ void svr_getopts(int argc, char ** argv) + #if DROPBEAR_DO_REEXEC && NON_INETD_MODE + /* For internal use by re-exec */ + case '2': +- svr_opts.reexec_child = 1; ++ next = &reexec_fd_arg; + break; + #endif + case 'p': +- nextisport = 1; +- break; ++ nextisport = 1; ++ break; + case 'P': + next = &svr_opts.pidfile; + break; +@@ -426,6 +428,13 @@ void svr_getopts(int argc, char ** argv) + dropbear_log(LOG_INFO, "Forced command set to '%s'", svr_opts.forced_command); + } + ++ if (reexec_fd_arg) { ++ if (m_str_to_uint(reexec_fd_arg, &svr_opts.reexec_childpipe) == DROPBEAR_FAILURE ++ || svr_opts.reexec_childpipe < 0) { ++ dropbear_exit("Bad -2"); ++ } ++ } ++ + #if INETD_MODE + if (svr_opts.inetdmode && ( + opts.usingsyslog == 0 -- 2.30.2