From d2d5e717f3d15516cf9756cea66e449cbe517c76 Mon Sep 17 00:00:00 2001 From: Eshan Kelkar Date: Sun, 10 Dec 2023 09:22:27 +0530 Subject: [PATCH] torture_sftp_limits.c: Change the test Test has been changed such that sftp_limits() is called when the limits@openssh.com extension is supported as well as when it is not supported. Also, a simple negative test has been added for NULL argument. Signed-off-by: Eshan Kelkar Reviewed-by: Jakub Jelen --- tests/client/torture_sftp_limits.c | 96 +++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 8 deletions(-) diff --git a/tests/client/torture_sftp_limits.c b/tests/client/torture_sftp_limits.c index f8b682f7..07ef9928 100644 --- a/tests/client/torture_sftp_limits.c +++ b/tests/client/torture_sftp_limits.c @@ -6,9 +6,14 @@ #include "sftp.c" #include +#include #include #include +#if HAVE_VALGRIND_VALGRIND_H + #include +#endif + static int sshd_setup(void **state) { torture_setup_sshd_server(state, false); @@ -62,27 +67,102 @@ static void torture_sftp_limits(void **state) { struct torture_state *s = *state; struct torture_sftp *t = s->ssh.tsftp; - sftp_limits_t li; - - if (!sftp_extension_supported(t->sftp, "limits@openssh.com", "1")) - skip(); + sftp_limits_t li = NULL; + int rc; li = sftp_limits(t->sftp); assert_non_null(li); - assert_int_not_equal(li->max_packet_length, 0); - assert_int_not_equal(li->max_read_length, 0); - assert_int_not_equal(li->max_write_length, 0); - assert_int_not_equal(li->max_open_handles, 0); + rc = sftp_extension_supported(t->sftp, "limits@openssh.com", "1"); + if (rc == 1) { + /* + * Tests are run against the OpenSSH server, hence we check for the + * specific limits used by OpenSSH. + */ + uint64_t openssh_max_packet_length = 256 * 1024; + uint64_t openssh_max_read_length = openssh_max_packet_length - 1024; + uint64_t openssh_max_write_length = openssh_max_packet_length - 1024; + size_t vg = 0; + + assert_int_equal(li->max_packet_length, openssh_max_packet_length); + assert_int_equal(li->max_read_length, openssh_max_read_length); + assert_int_equal(li->max_write_length, openssh_max_write_length); + + /* + * fds - File descriptors, w.r.to - With respect to + * + * Valgrind reserves some fds for itself and changes the rlimits + * w.r.to fds for the process its inspecting. Due to this reservation + * the rlimits w.r.to fds for our test may not be the same as the + * rlimits w.r.to fds seen by OpenSSH server (which Valgrind isn't + * inspecting). + * + * Valgrind changes the limits in such a way that after seeing the + * changed limits, the test cannot predict the original unchanged + * limits (which OpenSSH would be using). Hence, the test cannot + * determine the correct value of "max_open_handles" that the OpenSSH + * server should've sent. + * + * So if Valgrind is running our test, we don't provide any kind of + * check for max_open_handles. Check for >= 0 is also not provided in + * this case since that's always true for an uint64_t (an unsigned type) + */ +#if HAVE_VALGRIND_VALGRIND_H + vg = RUNNING_ON_VALGRIND; +#endif + + if (vg == 0) { + struct rlimit rlim = {0}; + uint64_t openssh_max_open_handles = 0; + + /* + * Get the resource limit for max file descriptors that a process + * can open. Since the client and the server run on the same machine + * in case of tests, this limit should be same for both (except the + * case when Valgrind runs the test) + */ + rc = getrlimit(RLIMIT_NOFILE, &rlim); + assert_int_equal(rc, 0); + if (rlim.rlim_cur > 5) { + /* + * Leaving file handles for stdout, stdin, stderr, syslog and + * a spare file handle, OpenSSH server allows the client to open + * at max (rlim.rlim_cur - 5) handles. + */ + openssh_max_open_handles = rlim.rlim_cur - 5; + } + + assert_int_equal(li->max_open_handles, openssh_max_open_handles); + } + } else { + /* Check for the default limits */ + assert_int_equal(li->max_packet_length, 34000); + assert_int_equal(li->max_read_length, 32768); + assert_int_equal(li->max_write_length, 32768); + assert_int_equal(li->max_open_handles, 0); + } sftp_limits_free(li); } +static void torture_sftp_limits_negative(void **state) +{ + sftp_limits_t li = NULL; + + (void)state; + li = sftp_limits(NULL); + assert_null(li); +} + int torture_run_tests(void) { int rc; struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(torture_sftp_limits, + session_setup, + session_teardown), + + cmocka_unit_test_setup_teardown(torture_sftp_limits_negative, session_setup, session_teardown) };