From 60d6179eaa65bba02eca219cc81300ed51ce30f4 Mon Sep 17 00:00:00 2001 From: Mingyuan Li <2560359315@qq.com> Date: Mon, 23 Feb 2026 23:31:56 +0800 Subject: [PATCH] tests: Add opendir handle exhaustion test for sftpserver Add torture_server_sftp_opendir_handles_exhaustion test that exercises the error path in process_opendir() when all SFTP handles are occupied. This covers the memory leak fix for h->name that was missing in the sftp_handle_alloc() failure path. The test exhausts all 256 handle slots with sftp_open(), then verifies that sftp_opendir() fails gracefully without crashing or leaking memory. Signed-off-by: Mingyuan Li <2560359315@qq.com> Reviewed-by: Jakub Jelen --- tests/server/torture_sftpserver.c | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/server/torture_sftpserver.c b/tests/server/torture_sftpserver.c index 5bf392c1..be473432 100644 --- a/tests/server/torture_sftpserver.c +++ b/tests/server/torture_sftpserver.c @@ -1130,6 +1130,46 @@ static void torture_server_sftp_handles_exhaustion(void **state) } } +static void torture_server_sftp_opendir_handles_exhaustion(void **state) +{ + struct test_server_st *tss = *state; + struct torture_state *s = NULL; + struct torture_sftp *tsftp = NULL; + char name[128] = {0}; + sftp_file handles[SFTP_HANDLES] = {0}; + sftp_dir dir = NULL; + sftp_session sftp = NULL; + int rc; + + assert_non_null(tss); + + s = tss->state; + assert_non_null(s); + + tsftp = s->ssh.tsftp; + assert_non_null(tsftp); + + sftp = tsftp->sftp; + assert_non_null(sftp); + + /* Occupy all handles with files */ + for (int i = 0; i < SFTP_HANDLES; i++) { + snprintf(name, sizeof(name), "%s/fn%d", tsftp->testdir, i); + handles[i] = sftp_open(sftp, name, O_WRONLY | O_CREAT, 0700); + assert_non_null(handles[i]); + } + + /* Opening a directory should fail gracefully without leaking h->name */ + dir = sftp_opendir(sftp, tsftp->testdir); + assert_null(dir); + + /* cleanup */ + for (int i = 0; i < SFTP_HANDLES; i++) { + rc = sftp_close(handles[i]); + assert_int_equal(rc, SSH_OK); + } +} + static void torture_server_sftp_handle_overrun(void **state) { struct test_server_st *tss = *state; @@ -1290,6 +1330,9 @@ int torture_run_tests(void) { cmocka_unit_test_setup_teardown(torture_server_sftp_handles_exhaustion, session_setup_sftp, session_teardown), + cmocka_unit_test_setup_teardown(torture_server_sftp_opendir_handles_exhaustion, + session_setup_sftp, + session_teardown), cmocka_unit_test_setup_teardown(torture_server_sftp_handle_overrun, session_setup_sftp, session_teardown),