comparison svr-main.c @ 1870:0dcc5b0d93fa

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.
author Matt Johnston <matt@ucc.asn.au>
date Tue, 01 Feb 2022 22:18:23 +0800
parents adfcdfb161a4
children 2c9d635a1c04
comparison
equal deleted inserted replaced
1869:d7247462fa0d 1870:0dcc5b0d93fa
34 static size_t listensockets(int *sock, size_t sockcount, int *maxfd); 34 static size_t listensockets(int *sock, size_t sockcount, int *maxfd);
35 static void sigchld_handler(int dummy); 35 static void sigchld_handler(int dummy);
36 static void sigsegv_handler(int); 36 static void sigsegv_handler(int);
37 static void sigintterm_handler(int fish); 37 static void sigintterm_handler(int fish);
38 static void main_inetd(void); 38 static void main_inetd(void);
39 static void main_noinetd(int argc, char ** argv); 39 static void main_noinetd(int argc, char ** argv, const char* multipath);
40 static void commonsetup(void); 40 static void commonsetup(void);
41 41
42 #if defined(DBMULTI_dropbear) || !DROPBEAR_MULTI 42 #if defined(DBMULTI_dropbear) || !DROPBEAR_MULTI
43 #if defined(DBMULTI_dropbear) && DROPBEAR_MULTI 43 #if defined(DBMULTI_dropbear) && DROPBEAR_MULTI
44 int dropbear_main(int argc, char ** argv) 44 int dropbear_main(int argc, char ** argv, const char* multipath)
45 #else 45 #else
46 int main(int argc, char ** argv) 46 int main(int argc, char ** argv)
47 #endif 47 #endif
48 { 48 {
49 #if !DROPBEAR_MULTI
50 const char* multipath = NULL;
51 #endif
52
49 _dropbear_exit = svr_dropbear_exit; 53 _dropbear_exit = svr_dropbear_exit;
50 _dropbear_log = svr_dropbear_log; 54 _dropbear_log = svr_dropbear_log;
51 55
52 disallow_core(); 56 disallow_core();
53 57
78 /* notreached */ 82 /* notreached */
79 } 83 }
80 #endif 84 #endif
81 85
82 #if NON_INETD_MODE 86 #if NON_INETD_MODE
83 main_noinetd(argc, argv); 87 main_noinetd(argc, argv, multipath);
84 /* notreached */ 88 /* notreached */
85 #endif 89 #endif
86 90
87 dropbear_exit("Compiled without normal mode, can't run without -i\n"); 91 dropbear_exit("Compiled without normal mode, can't run without -i\n");
88 return -1; 92 return -1;
119 /* notreached */ 123 /* notreached */
120 } 124 }
121 #endif /* INETD_MODE */ 125 #endif /* INETD_MODE */
122 126
123 #if NON_INETD_MODE 127 #if NON_INETD_MODE
124 static void main_noinetd(int argc, char ** argv) { 128 static void main_noinetd(int argc, char ** argv, const char* multipath) {
125 fd_set fds; 129 fd_set fds;
126 unsigned int i, j; 130 unsigned int i, j;
127 int val; 131 int val;
128 int maxsock = -1; 132 int maxsock = -1;
129 int listensocks[MAX_LISTEN_ADDR]; 133 int listensocks[MAX_LISTEN_ADDR];
161 for (i = 0; i < listensockcount; i++) { 165 for (i = 0; i < listensockcount; i++) {
162 FD_SET(listensocks[i], &fds); 166 FD_SET(listensocks[i], &fds);
163 } 167 }
164 168
165 #if DROPBEAR_DO_REEXEC 169 #if DROPBEAR_DO_REEXEC
166 execfd = open(argv[0], O_CLOEXEC|O_RDONLY); 170 if (multipath) {
171 execfd = open(multipath, O_CLOEXEC|O_RDONLY);
172 } else {
173 execfd = open(argv[0], O_CLOEXEC|O_RDONLY);
174 }
167 if (execfd < 0) { 175 if (execfd < 0) {
168 /* Just fallback to straight fork */ 176 /* Just fallback to straight fork */
169 TRACE(("Couldn't open own binary %s, disabling re-exec: %s", argv[0], strerror(errno))) 177 TRACE(("Couldn't open own binary %s, disabling re-exec: %s", argv[0], strerror(errno)))
170 } 178 }
171 #endif 179 #endif
336 344
337 m_close(childpipe[0]); 345 m_close(childpipe[0]);
338 346
339 if (execfd >= 0) { 347 if (execfd >= 0) {
340 #if DROPBEAR_DO_REEXEC 348 #if DROPBEAR_DO_REEXEC
341 /* Add "-2" to the args and re-execute ourself */ 349 /* Add "-2" to the args and re-execute ourself. */
342 char **new_argv = m_malloc(sizeof(char*) * (argc+2)); 350 char **new_argv = m_malloc(sizeof(char*) * (argc+3));
343 memcpy(new_argv, argv, sizeof(char*) * argc); 351 int pos0 = 0, new_argc = argc+1;
344 new_argv[argc] = "-2"; 352
345 new_argv[argc+1] = NULL; 353 /* We need to specially handle "dropbearmulti dropbear". */
354 if (multipath) {
355 new_argv[0] = (char*)multipath;
356 pos0 = 1;
357 new_argc++;
358 }
359
360 memcpy(&new_argv[pos0], argv, sizeof(char*) * argc);
361 new_argv[new_argc-1] = "-2";
362 new_argv[new_argc] = NULL;
346 363
347 if ((dup2(childsock, STDIN_FILENO) < 0)) { 364 if ((dup2(childsock, STDIN_FILENO) < 0)) {
348 dropbear_exit("dup2 failed: %s", strerror(errno)); 365 dropbear_exit("dup2 failed: %s", strerror(errno));
349 } 366 }
350 if (fcntl(childsock, F_SETFD, FD_CLOEXEC) < 0) { 367 if (fcntl(childsock, F_SETFD, FD_CLOEXEC) < 0) {