Merged upstream 7 Oct 2026 Upstream bug fix in ProFTPD
ProFTPD: keyboard-interactive answers matched to the wrong PAM prompts
Our scanner flagged that the mod_sftp_pam module of ProFTPD, which lets SFTP logins authenticate through PAM with keyboard-interactive authentication, read the client’s answers by the wrong index. When a PAM module sent an informational message before a prompt in the same conversation, the prompt got the wrong answer and the code read past the end of the answers array. Maintainer TJ Saunders merged our fix on 7 October 2026.
What was wrong
sftppam_converse() sends the client only the PAM prompts (PAM_PROMPT_ECHO_ON and PAM_PROMPT_ECHO_OFF) as keyboard-interactive challenges. Informational and error messages (PAM_TEXT_INFO, PAM_ERROR_MSG) are shown as a banner or logged instead. ProFTPD requires exactly one answer per challenge, so the client returns one answer per prompt.
The loop that hands the answers back to PAM, however, indexed them by the position of the PAM message, not by the position of the prompt. With the messages [PAM_TEXT_INFO, PAM_PROMPT_ECHO_OFF], only one challenge is sent, yet the code read recvd_responses[1] and passed it to strdup(): a heap out-of-bounds read.
PAM modules may legitimately do this. pam-krb5, for example, sends the Kerberos prompter’s banner as PAM_TEXT_INFO together with the prompts during an expired-password change. With such a PAM stack, keyboard-interactive login failed or the session process could crash. A client cannot trigger it on its own; it depends on the server’s PAM configuration.
How it was fixed
The fix keeps a separate index into the received answers and advances it only for prompts, so it can never pass the number of answers received:
- uint32_t recvd_count = 0;
+ uint32_t recvd_count = 0, recvd_idx = 0;
...
case PAM_PROMPT_ECHO_OFF:
- res[i].resp = strdup(recvd_responses[i]);
+ res[i].resp = strdup(recvd_responses[recvd_idx++]);
ProFTPD’s contrib modules have no unit-test harness, so we checked the change with a standalone AddressSanitizer harness around the conversation function. The three mixed message lists that produced heap-buffer-overflow reads before the fix pass after it. Maintainer TJ Saunders (Castaglia) replied on the pull request:
“I'll be merging this shortly. Thanks for the patch/fix!”
Timeline
- 30 Sep 2026. A scan of the ProFTPD source tree (411 files, model qwen3.8-27b) flagged
sftppam_converse(). Three triage rounds rated the finding valid. - 2 Oct. We confirmed the index mix-up with the AddressSanitizer harness and opened pull request #2355.
- 7 Oct. TJ Saunders merged it into master. As of 9 Oct 2026 it is not in a tagged release yet.
How to read this
The scanner pointed at the right function, but its triage overstated the reach: it assumed a client could send fewer answers than prompts. Reading the receiving code ruled that out and narrowed the issue to PAM stacks that mix messages and prompts. That narrower description is what went upstream. Findings are leads for people, not verdicts.