From: Peter Korsgaard <[email protected]> Otherwise we can end up with an empty host key, breaking logins.
E.G.: Run dropbear -R and pull power before the host key is writting to disk. After reboot we have: ls -l /etc/dropbear/ -rw------- 1 root root 0 Oct 28 10:41 dropbear_ecdsa_host_key Which dropbear will try to read and fail: [599] Oct 28 10:43:43 Early exit: Bad buf_getptr Signed-off-by: Peter Korsgaard <[email protected]> --- gensignkey.c | 1 + svr-kex.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/gensignkey.c b/gensignkey.c index 338bbef..06fdfd3 100644 --- a/gensignkey.c +++ b/gensignkey.c @@ -41,6 +41,7 @@ static int buf_writefile(buffer * buf, const char * filename) { out: if (fd >= 0) { + fsync(fd); m_close(fd); } return ret; diff --git a/svr-kex.c b/svr-kex.c index 337c377..8e76489 100644 --- a/svr-kex.c +++ b/svr-kex.c @@ -89,6 +89,7 @@ static void svr_ensure_hostkey() { const char* fn = NULL; char *fn_temp = NULL; + char *fn_dir = NULL; enum signkey_type type = ses.newkeys->algo_hostkey; void **hostkey = signkey_key_ptr(svr_opts.hostkey, type); int ret = DROPBEAR_FAILURE; @@ -142,6 +143,22 @@ static void svr_ensure_hostkey() { } } +#ifdef HAVE_LIBGEN_H + /* ensure directory update is flushed to disk */ + fn_dir = strdup(fn); + if (fn_dir != NULL) { + char *dir = dirname(fn_dir); + int dirfd = open(dir, O_RDONLY); + + if (dirfd != -1) { + fsync(dirfd); + close(dirfd); + } + + free(fn_dir); + } +#endif + ret = readhostkey(fn, svr_opts.hostkey, &type); if (ret == DROPBEAR_SUCCESS) { -- 2.1.0
