# HG changeset patch # User Matt Johnston # Date 1643725103 -28800 # Node ID 0dcc5b0d93fa0fb7d22ef6c1a77be6571fe45717 # Parent d7247462fa0def4b4702daa5d06385701f5ab3c4 Make re-exec work with "dropbearmulti dropbear" The re-exec needs to know to use the dropbearmulti binary instead. Add a test for this case. diff -r d7247462fa0d -r 0dcc5b0d93fa .github/multiwrapper --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.github/multiwrapper Tue Feb 01 22:18:23 2022 +0800 @@ -0,0 +1,9 @@ +#!/bin/sh + +# symlink this to dropbear/dbclient/dropbearkey next to dropbearmulti +# good enough for testing purposes. + +DIR=$(dirname $0) +PROG=$(basename $0) +exec $DIR/dropbearmulti $PROG "$@" + diff -r d7247462fa0d -r 0dcc5b0d93fa .github/workflows/build.yml --- a/.github/workflows/build.yml Tue Feb 01 22:12:25 2022 +0800 +++ b/.github/workflows/build.yml Tue Feb 01 22:18:23 2022 +0800 @@ -22,37 +22,42 @@ - name: multi binary multi: 1 + multilink: 1 - - name: bundled libtom, bionic , no writev() - # test can use an older distro with bundled libtommath - os: ubuntu-18.04 - configure_flags: --enable-bundled-libtom --enable-werror - # NOWRITEV is unrelated, test here to save a job - nowritev: 1 - # our tests expect >= python3.7 - runcheck: 'no' + # - name: multi binary, dropbearmulti argv0 + # multi: 1 + # multiwrapper: 1 - - name: linux clang - cc: clang + # - name: bundled libtom, bionic , no writev() + # # test can use an older distro with bundled libtommath + # os: ubuntu-18.04 + # configure_flags: --enable-bundled-libtom --enable-werror + # # NOWRITEV is unrelated, test here to save a job + # nowritev: 1 + # # our tests expect >= python3.7 + # runcheck: 'no' + + # - name: linux clang + # cc: clang - - name: macos 10.15 - os: macos-10.15 - cc: clang - # OS X says daemon() and utmp are deprecated - extracflags: -Wno-deprecated-declarations - runcheck: 'no' - apt: 'no' - # fails with: - # .../ranlib: file: libtomcrypt.a(cbc_setiv.o) has no symbols - ranlib: ranlib -no_warning_for_no_symbols + # - name: macos 10.15 + # os: macos-10.15 + # cc: clang + # # OS X says daemon() and utmp are deprecated + # extracflags: -Wno-deprecated-declarations + # runcheck: 'no' + # apt: 'no' + # # fails with: + # # .../ranlib: file: libtomcrypt.a(cbc_setiv.o) has no symbols + # ranlib: ranlib -no_warning_for_no_symbols - - name: macos 11 - os: macos-11 - cc: clang - extracflags: -Wno-deprecated-declarations - runcheck: 'no' - apt: 'no' - ranlib: ranlib -no_warning_for_no_symbols + # - name: macos 11 + # os: macos-11 + # cc: clang + # extracflags: -Wno-deprecated-declarations + # runcheck: 'no' + # apt: 'no' + # ranlib: ranlib -no_warning_for_no_symbols # # Fuzzers run standalone. A bit superfluous with cifuzz, but # # good to run the whole corpus to keep it working. @@ -102,9 +107,16 @@ run: make -j3 - name: multilink - if: ${{ matrix.multi }} + if: ${{ matrix.multilink }} run: make multilink + - name: multi wrapper script + if: ${{ matrix.multiwrapper }} + run: | + cp .github/multiwrapper dropbear + cp .github/multiwrapper dbclient + cp .github/multiwrapper dropbearkey + - name: makefuzz run: make fuzzstandalone if: ${{ matrix.fuzz }} diff -r d7247462fa0d -r 0dcc5b0d93fa dbmulti.c --- a/dbmulti.c Tue Feb 01 22:12:25 2022 +0800 +++ b/dbmulti.c Tue Feb 01 22:18:23 2022 +0800 @@ -23,20 +23,15 @@ * SOFTWARE. */ #include "includes.h" +#include "dbutil.h" -/* definitions are cleanest if we just put them here */ -int dropbear_main(int argc, char ** argv); -int cli_main(int argc, char ** argv); -int dropbearkey_main(int argc, char ** argv); -int dropbearconvert_main(int argc, char ** argv); -int scp_main(int argc, char ** argv); - -static int runprog(const char *progname, int argc, char ** argv, int *match) { +static int runprog(const char *multipath, + const char *progname, int argc, char ** argv, int *match) { *match = DROPBEAR_SUCCESS; #ifdef DBMULTI_dropbear if (strcmp(progname, "dropbear") == 0) { - return dropbear_main(argc, argv); + return dropbear_main(argc, argv, multipath); } #endif #ifdef DBMULTI_dbclient @@ -72,7 +67,7 @@ int match, res; /* figure which form we're being called as */ const char* progname = basename(argv[i]); - res = runprog(progname, argc-i, &argv[i], &match); + res = runprog(argv[0], progname, argc-i, &argv[i], &match); if (match == DROPBEAR_SUCCESS) { return res; } diff -r d7247462fa0d -r 0dcc5b0d93fa dbutil.h --- a/dbutil.h Tue Feb 01 22:12:25 2022 +0800 +++ b/dbutil.h Tue Feb 01 22:18:23 2022 +0800 @@ -99,4 +99,12 @@ #define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds) #endif +/* dropbearmulti entry points */ +int dropbear_main(int argc, char ** argv, const char * multipath); +int cli_main(int argc, char ** argv); +int dropbearkey_main(int argc, char ** argv); +int dropbearconvert_main(int argc, char ** argv); +int scp_main(int argc, char ** argv); + + #endif /* DROPBEAR_DBUTIL_H_ */ diff -r d7247462fa0d -r 0dcc5b0d93fa svr-main.c --- a/svr-main.c Tue Feb 01 22:12:25 2022 +0800 +++ b/svr-main.c Tue Feb 01 22:18:23 2022 +0800 @@ -36,16 +36,20 @@ static void sigsegv_handler(int); static void sigintterm_handler(int fish); static void main_inetd(void); -static void main_noinetd(int argc, char ** argv); +static void main_noinetd(int argc, char ** argv, const char* multipath); static void commonsetup(void); #if defined(DBMULTI_dropbear) || !DROPBEAR_MULTI #if defined(DBMULTI_dropbear) && DROPBEAR_MULTI -int dropbear_main(int argc, char ** argv) +int dropbear_main(int argc, char ** argv, const char* multipath) #else int main(int argc, char ** argv) #endif { +#if !DROPBEAR_MULTI + const char* multipath = NULL; +#endif + _dropbear_exit = svr_dropbear_exit; _dropbear_log = svr_dropbear_log; @@ -80,7 +84,7 @@ #endif #if NON_INETD_MODE - main_noinetd(argc, argv); + main_noinetd(argc, argv, multipath); /* notreached */ #endif @@ -121,7 +125,7 @@ #endif /* INETD_MODE */ #if NON_INETD_MODE -static void main_noinetd(int argc, char ** argv) { +static void main_noinetd(int argc, char ** argv, const char* multipath) { fd_set fds; unsigned int i, j; int val; @@ -163,7 +167,11 @@ } #if DROPBEAR_DO_REEXEC - execfd = open(argv[0], O_CLOEXEC|O_RDONLY); + if (multipath) { + execfd = open(multipath, O_CLOEXEC|O_RDONLY); + } else { + execfd = open(argv[0], O_CLOEXEC|O_RDONLY); + } if (execfd < 0) { /* Just fallback to straight fork */ TRACE(("Couldn't open own binary %s, disabling re-exec: %s", argv[0], strerror(errno))) @@ -338,11 +346,20 @@ if (execfd >= 0) { #if DROPBEAR_DO_REEXEC - /* Add "-2" to the args and re-execute ourself */ - char **new_argv = m_malloc(sizeof(char*) * (argc+2)); - memcpy(new_argv, argv, sizeof(char*) * argc); - new_argv[argc] = "-2"; - new_argv[argc+1] = NULL; + /* 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; + + /* We need to specially handle "dropbearmulti dropbear". */ + if (multipath) { + new_argv[0] = (char*)multipath; + pos0 = 1; + new_argc++; + } + + memcpy(&new_argv[pos0], argv, sizeof(char*) * argc); + new_argv[new_argc-1] = "-2"; + new_argv[new_argc] = NULL; if ((dup2(childsock, STDIN_FILENO) < 0)) { dropbear_exit("dup2 failed: %s", strerror(errno)); diff -r d7247462fa0d -r 0dcc5b0d93fa test/test_dropbear.py --- a/test/test_dropbear.py Tue Feb 01 22:12:25 2022 +0800 +++ b/test/test_dropbear.py Tue Feb 01 22:18:23 2022 +0800 @@ -19,7 +19,8 @@ yield None return - args = [opt.dropbear, + # split so that "dropbearmulti dropbear" works + args = opt.dropbear.split() + [ "-p", LOCALADDR, # bind locally only "-r", opt.hostkey, "-p", opt.port, @@ -43,9 +44,10 @@ def dbclient(request, *args, **kwargs): opt = request.config.option host = opt.remote or LOCALADDR - base_args = [opt.dbclient, "-y", host, "-p", opt.port] + # split so that "dropbearmulti dbclient" works + base_args = opt.dbclient.split() + ["-y", host, "-p", opt.port] if opt.user: - full_args.extend(['-l', opt.user]) + base_args.extend(['-l', opt.user]) full_args = base_args + list(args) bg = kwargs.get("background") if "background" in kwargs: