aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Dion <odion@efficios.com>2024-03-08 10:59:57 -0500
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>2024-03-08 15:56:17 -0500
commitc15b99f6c3b4bf79b936f57355a4a7cd2ea92e51 (patch)
tree851dff6bde2c0bcc58e9235a39522dd9dae5899d
parentf510ddc54559adda6000ec59a80011f90fb8c60d (diff)
downloadlibrseq-c15b99f6c3b4bf79b936f57355a4a7cd2ea92e51.tar.gz
tests/mempool_test: Add robust testing
Change-Id: I0e7c9dd7ad03070f0524edb4252cb11988418108 Signed-off-by: Olivier Dion <odion@efficios.com> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-rw-r--r--tests/mempool_test.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/tests/mempool_test.c b/tests/mempool_test.c
index 6f8597a..395d3b9 100644
--- a/tests/mempool_test.c
+++ b/tests/mempool_test.c
@@ -15,6 +15,8 @@
#include <sys/time.h>
#include <inttypes.h>
#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
#include <rseq/mempool.h>
@@ -88,6 +90,108 @@ static void test_mempool_fill(size_t stride)
ok(ret == 0, "Destroy mempool");
}
+static void test_robust_double_free(struct rseq_percpu_pool *pool)
+{
+ struct test_data __rseq_percpu *ptr;
+
+ ptr = (struct test_data __rseq_percpu *) rseq_percpu_malloc(pool);
+
+ rseq_percpu_free(ptr);
+ rseq_percpu_free(ptr);
+}
+
+static void test_robust_corrupt_after_free(struct rseq_percpu_pool *pool)
+{
+ struct test_data __rseq_percpu *ptr;
+ struct test_data *cpuptr;
+
+ ptr = (struct test_data __rseq_percpu *) rseq_percpu_malloc(pool);
+ cpuptr = (struct test_data *) rseq_percpu_ptr(ptr, 0);
+
+ rseq_percpu_free(ptr);
+ cpuptr->value = (uintptr_t) test_robust_corrupt_after_free;
+
+ rseq_percpu_pool_destroy(pool);
+}
+
+static void test_robust_memory_leak(struct rseq_percpu_pool *pool)
+{
+ (void) rseq_percpu_malloc(pool);
+
+ rseq_percpu_pool_destroy(pool);
+}
+
+static void test_robust_free_list_corruption(struct rseq_percpu_pool *pool)
+{
+ struct test_data __rseq_percpu *ptr;
+ struct test_data *cpuptr;
+
+ ptr = (struct test_data __rseq_percpu *) rseq_percpu_malloc(pool);
+ cpuptr = (struct test_data *) rseq_percpu_ptr(ptr, 0);
+
+ rseq_percpu_free(ptr);
+
+ cpuptr->value = (uintptr_t) cpuptr;
+
+ (void) rseq_percpu_malloc(pool);
+ (void) rseq_percpu_malloc(pool);
+}
+
+static int run_robust_test(void (*test)(struct rseq_percpu_pool*),
+ struct rseq_percpu_pool *pool)
+{
+ pid_t cpid;
+ int status;
+
+ cpid = fork();
+
+ switch (cpid) {
+ case -1:
+ return 0;
+ case 0:
+ test(pool);
+ _exit(EXIT_FAILURE);
+ default:
+ waitpid(cpid, &status, 0);
+ }
+
+ if (WIFSIGNALED(status) &&
+ (SIGABRT == WTERMSIG(status)))
+ return 1;
+
+ return 0;
+}
+
+static void run_robust_tests(void)
+{
+ struct rseq_pool_attr *attr;
+ struct rseq_percpu_pool *pool;
+
+ attr = rseq_pool_attr_create();
+
+ rseq_pool_attr_set_robust(attr);
+
+ pool = rseq_percpu_pool_create("mempool-robust",
+ sizeof(void*), RSEQ_PERCPU_STRIDE, 1,
+ attr);
+
+ rseq_pool_attr_destroy(attr);
+
+ ok(run_robust_test(test_robust_double_free, pool),
+ "robust-double-free");
+
+ ok(run_robust_test(test_robust_corrupt_after_free, pool),
+ "robust-corrupt-after-free");
+
+ ok(run_robust_test(test_robust_memory_leak, pool),
+ "robust-memory-leak");
+
+ ok(run_robust_test(test_robust_free_list_corruption, pool),
+ "robust-free-list-corruption");
+
+ rseq_percpu_pool_destroy(pool);
+}
+
int main(void)
{
size_t len;
@@ -99,5 +203,7 @@ int main(void)
test_mempool_fill(len);
}
+ run_robust_tests();
+
exit(exit_status());
}