Add test for F_SETLK as this is needs to be 64-bit aware on 32-bit userspace
authorAndrew Bartlett <abartlet@samba.org>
Fri, 5 May 2023 01:15:51 +0000 (13:15 +1200)
committerAndreas Schneider <asn@samba.org>
Mon, 8 May 2023 10:34:59 +0000 (12:34 +0200)
If this is not correctly routed to fcntl64 (where that exists) then an
incorrect thunking could be applied breaking the functionality.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15367

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
tests/CMakeLists.txt
tests/test_fcntl_lock.c [new file with mode: 0644]

index b1a3c6c5adc672dd5a54be3dba34638c54f5bc34..e35c2581ff5ea0492bcbc656ca1b9134a8a9a427 100644 (file)
@@ -58,6 +58,7 @@ set(SWRAP_TESTS
     test_tcp_listen
     test_tcp_dup2
     test_fcntl
+    test_fcntl_lock
     test_echo_tcp_connect
     test_echo_tcp_bind
     test_echo_tcp_socket_options
diff --git a/tests/test_fcntl_lock.c b/tests/test_fcntl_lock.c
new file mode 100644 (file)
index 0000000..98cf7c0
--- /dev/null
@@ -0,0 +1,86 @@
+#include "torture.h"
+
+#include <cmocka.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+static int setup(void **state)
+{
+       char test_tmpdir[256];
+       const char *p;
+
+       (void) state; /* unused */
+
+       snprintf(test_tmpdir, sizeof(test_tmpdir), "/tmp/test_socket_wrapper_XXXXXX");
+
+       p = mkdtemp(test_tmpdir);
+       assert_non_null(p);
+
+       *state = strdup(p);
+       return 0;
+}
+
+static int teardown(void **state)
+{
+       char remove_cmd[PATH_MAX] = {0};
+       char *s = (char *)*state;
+       int rc;
+
+       if (s == NULL) {
+               return -1;
+       }
+
+       snprintf(remove_cmd, sizeof(remove_cmd), "rm -rf %s", s);
+       free(s);
+
+       rc = system(remove_cmd);
+       if (rc < 0) {
+               fprintf(stderr, "%s failed: %s", remove_cmd, strerror(errno));
+       }
+
+       return rc;
+}
+
+static void test_fcntl_lock(void **state)
+{
+       char file[PATH_MAX];
+       int fd, rc;
+       struct flock lock;
+       char *s = (char *)*state;
+
+       rc = snprintf(file, sizeof(file), "%s/file", s);
+       assert_in_range(rc, 0, PATH_MAX);
+
+       fd = open(file, O_CREAT, 0600);
+       assert_return_code(fd, errno);
+
+       lock.l_type = F_RDLCK;
+       lock.l_whence = SEEK_SET;
+       lock.l_start = 0;
+       lock.l_len = 4;
+       lock.l_pid = 0;
+
+       rc = fcntl(fd, F_SETLK, &lock);
+       assert_return_code(rc, errno);
+
+       rc = unlink(file);
+       assert_return_code(rc, errno);
+}
+
+
+int main(void) {
+       int rc;
+
+       const struct CMUnitTest tcp_fcntl_lock_tests[] = {
+               cmocka_unit_test(test_fcntl_lock),
+       };
+
+       rc = cmocka_run_group_tests(tcp_fcntl_lock_tests, setup, teardown);
+
+       return rc;
+}