https://bugzilla.mindrot.org/show_bug.cgi?id=2167
--- Comment #4 from Tetsuo Handa <[email protected]> --- OK. I found the exact location. fatal("fork of unprivileged child failed") calls cleanup_exit(255). cleanup_exit(255) calls destroy_sensitive_data(1). destroy_sensitive_data(1) calls mm_audit_destroy_sensitive_data(fp, pid, uid). mm_audit_destroy_sensitive_data() uses global pmonitor->m_recvfd which now references a socket pair. ---------- mm_audit_destroy_sensitive_data() in monitor_wrap.c ---------- void mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) { Buffer m; buffer_init(&m); buffer_put_cstring(&m, fp); buffer_put_int64(&m, pid); buffer_put_int64(&m, uid); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, &m); buffer_free(&m); } ---------- mm_audit_destroy_sensitive_data() in monitor_wrap.c ---------- Regarding privsep_preauth(), pmonitor = monitor_init() causes this problem when fork() fails. Fortunately, timeout was previously configured via alarm() which will eventually terminate the process even if fork() failed. ---------- privsep_preauth() in sshd.c ---------- static int privsep_preauth(Authctxt *authctxt) { int status; pid_t pid; /* Set up unprivileged child process to deal with network data */ pmonitor = monitor_init(); /* Store a pointer to the kex for later rekeying */ pmonitor->m_pkex = &xxx_kex; pid = fork(); if (pid == -1) { fatal("fork of unprivileged child failed"); (...snipped...) ---------- privsep_preauth() in sshd.c ---------- Regarding privsep_postauth(), monitor_reinit(pmonitor) causes this problem when fork() fails. Unfortunately, timeout previously configured via alarm() was disabled, which results in forever wait when fork() failed. ---------- privsep_postauth() in sshd.c ---------- static void privsep_postauth(Authctxt *authctxt) { u_int32_t rnd[256]; #ifdef DISABLE_FD_PASSING if (1) { #else if (authctxt->pw->pw_uid == 0 || options.use_login) { #endif /* File descriptor passing is broken or root login */ use_privsep = 0; goto skip; } /* New socket pair */ monitor_reinit(pmonitor); pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) fatal("fork of unprivileged child failed"); (...snipped...) ---------- privsep_postauth() in sshd.c ---------- I confirmed that the patch in Comment 3 can fix this problem. -- You are receiving this mail because: You are watching the assignee of the bug. You are watching someone on the CC list of the bug. _______________________________________________ openssh-bugs mailing list [email protected] https://lists.mindrot.org/mailman/listinfo/openssh-bugs
