@@ -472,6 +472,7 @@ tests_ovstest_SOURCES = \
tests/test-packets.c \
tests/test-random.c \
tests/test-rcu.c \
+ tests/test-rcu-uaf.c \
tests/test-reconnect.c \
tests/test-rstp.c \
tests/test-sflow.c \
@@ -261,6 +261,39 @@ AT_KEYWORDS([rcu])
AT_CHECK([ovstest test-rcu], [0], [])
AT_CLEANUP
+AT_SETUP([rcu quiesce use-after-free detection])
+AT_SKIP_IF([test "$IS_WIN32" = "yes"])
+AT_SKIP_IF([test "$ASAN_ENABLED" = "no"])
+# SIGABRT + 128
+exit_status=134
+AT_KEYWORDS([rcu asan])
+AT_CHECK([ovstest test-rcu-uaf quiesce], [$exit_status], [ignore], [ignore])
+# ASAN report is expected on success.
+rm asan.*
+AT_CLEANUP
+
+AT_SETUP([rcu try-quiesce use-after-free detection])
+AT_SKIP_IF([test "$IS_WIN32" = "yes"])
+AT_SKIP_IF([test "$ASAN_ENABLED" = "no"])
+# SIGABRT + 128
+exit_status=134
+AT_KEYWORDS([rcu asan])
+AT_CHECK([ovstest test-rcu-uaf try-quiesce], [$exit_status], [ignore], [ignore])
+# ASAN report is expected on success.
+rm asan.*
+AT_CLEANUP
+
+AT_SETUP([rcu quiesce-start-end use-after-free detection])
+AT_SKIP_IF([test "$IS_WIN32" = "yes"])
+AT_SKIP_IF([test "$ASAN_ENABLED" = "no"])
+AT_KEYWORDS([rcu asan])
+# SIGABRT + 128
+exit_status=134
+AT_CHECK([ovstest test-rcu-uaf quiesce-start-end], [$exit_status], [ignore], [ignore])
+# ASAN report is expected on success.
+rm asan.*
+AT_CLEANUP
+
AT_SETUP([stopwatch module])
AT_CHECK([ovstest test-stopwatch], [0], [......
], [ignore])
new file mode 100644
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2021 NVIDIA Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <getopt.h>
+
+#include <config.h>
+
+#include "ovs-thread.h"
+#include "ovs-rcu.h"
+#include "ovstest.h"
+#include "util.h"
+
+enum ovsrcu_uaf_type {
+ OVSRCU_UAF_QUIESCE,
+ OVSRCU_UAF_TRY_QUIESCE,
+ OVSRCU_UAF_QUIESCE_START_END,
+};
+
+static void *
+rcu_uaf_main(void *aux)
+{
+ enum ovsrcu_uaf_type *type = aux;
+ char *xx = xmalloc(2);
+
+ xx[0] = 'a';
+ ovsrcu_postpone(free, xx);
+ switch (*type) {
+ case OVSRCU_UAF_QUIESCE:
+ ovsrcu_quiesce();
+ break;
+ case OVSRCU_UAF_TRY_QUIESCE:
+ while (ovsrcu_try_quiesce()) {
+ ;
+ }
+ break;
+ case OVSRCU_UAF_QUIESCE_START_END:
+ ovsrcu_quiesce_start();
+ ovsrcu_quiesce_end();
+ break;
+ default:
+ OVS_NOT_REACHED();
+ }
+ xx[1] = 'b';
+
+ return NULL;
+}
+
+static void
+usage(char *test_name)
+{
+ fprintf(stderr, "Usage: %s <quiesce|try-quiesce|quiesce-start-end>\n",
+ test_name);
+}
+
+static void
+test_rcu_uaf(int argc, char *argv[])
+{
+ char **args = argv + optind - 1;
+ enum ovsrcu_uaf_type type;
+ pthread_t quiescer;
+
+ if (argc - optind != 1) {
+ usage(args[0]);
+ return;
+ }
+
+ set_program_name(argv[0]);
+
+ if (!strcmp(args[1], "quiesce")) {
+ type = OVSRCU_UAF_QUIESCE;
+ } else if (!strcmp(args[1], "try-quiesce")) {
+ type = OVSRCU_UAF_TRY_QUIESCE;
+ } else if (!strcmp(args[1], "quiesce-start-end")) {
+ type = OVSRCU_UAF_QUIESCE_START_END;
+ } else {
+ usage(args[0]);
+ return;
+ }
+
+ /* Need to create a separate thread, to support try-quiesce. */
+ quiescer = ovs_thread_create("rcu-uaf", rcu_uaf_main, &type);
+ xpthread_join(quiescer, NULL);
+}
+
+OVSTEST_REGISTER("test-rcu-uaf", test_rcu_uaf);
When using the RCU mechanism and deferring memory reclamation, potential use-after-free due to incorrect use of RCU can be hidden. Add a test triggering a UAF event. When the test suite is built with AddressSanitizer support, verify that the event triggers and the tool is usable with RCU. Signed-off-by: Gaetan Rivet <grive@u256.net> --- tests/automake.mk | 1 + tests/library.at | 33 +++++++++++++++ tests/test-rcu-uaf.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 tests/test-rcu-uaf.c