Mercurial > dropbear
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) { |