list_debug: Introduce inline wrappers for debug checks
authorMarco Elver <elver@google.com>
Fri, 11 Aug 2023 15:18:39 +0000 (17:18 +0200)
committerKees Cook <keescook@chromium.org>
Tue, 15 Aug 2023 21:57:24 +0000 (14:57 -0700)
Turn the list debug checking functions __list_*_valid() into inline
functions that wrap the out-of-line functions. Care is taken to ensure
the inline wrappers are always inlined, so that additional compiler
instrumentation (such as sanitizers) does not result in redundant
outlining.

This change is preparation for performing checks in the inline wrappers.

No functional change intended.

Signed-off-by: Marco Elver <elver@google.com>
Link: https://lore.kernel.org/r/20230811151847.1594958-2-elver@google.com
Signed-off-by: Kees Cook <keescook@chromium.org>
arch/arm64/kvm/hyp/nvhe/list_debug.c
include/linux/list.h
lib/list_debug.c

index d68abd7ea124068fe4a0d3e496bfbf0a30d44aa7..16266a939a4cd16b32e4ff1b83d95c0838f884c1 100644 (file)
@@ -26,8 +26,8 @@ static inline __must_check bool nvhe_check_data_corruption(bool v)
 
 /* The predicates checked here are taken from lib/list_debug.c. */
 
-bool __list_add_valid(struct list_head *new, struct list_head *prev,
-                     struct list_head *next)
+bool __list_add_valid_or_report(struct list_head *new, struct list_head *prev,
+                               struct list_head *next)
 {
        if (NVHE_CHECK_DATA_CORRUPTION(next->prev != prev) ||
            NVHE_CHECK_DATA_CORRUPTION(prev->next != next) ||
@@ -37,7 +37,7 @@ bool __list_add_valid(struct list_head *new, struct list_head *prev,
        return true;
 }
 
-bool __list_del_entry_valid(struct list_head *entry)
+bool __list_del_entry_valid_or_report(struct list_head *entry)
 {
        struct list_head *prev, *next;
 
index f10344dbad4dfe5f51f7cce825884d4923c66c08..130c6a1bb45cb996fa14dd5b6db5f52c4d75d59c 100644 (file)
@@ -39,10 +39,39 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
 }
 
 #ifdef CONFIG_DEBUG_LIST
-extern bool __list_add_valid(struct list_head *new,
-                             struct list_head *prev,
-                             struct list_head *next);
-extern bool __list_del_entry_valid(struct list_head *entry);
+/*
+ * Performs the full set of list corruption checks before __list_add().
+ * On list corruption reports a warning, and returns false.
+ */
+extern bool __list_add_valid_or_report(struct list_head *new,
+                                      struct list_head *prev,
+                                      struct list_head *next);
+
+/*
+ * Performs list corruption checks before __list_add(). Returns false if a
+ * corruption is detected, true otherwise.
+ */
+static __always_inline bool __list_add_valid(struct list_head *new,
+                                            struct list_head *prev,
+                                            struct list_head *next)
+{
+       return __list_add_valid_or_report(new, prev, next);
+}
+
+/*
+ * Performs the full set of list corruption checks before __list_del_entry().
+ * On list corruption reports a warning, and returns false.
+ */
+extern bool __list_del_entry_valid_or_report(struct list_head *entry);
+
+/*
+ * Performs list corruption checks before __list_del_entry(). Returns false if a
+ * corruption is detected, true otherwise.
+ */
+static __always_inline bool __list_del_entry_valid(struct list_head *entry)
+{
+       return __list_del_entry_valid_or_report(entry);
+}
 #else
 static inline bool __list_add_valid(struct list_head *new,
                                struct list_head *prev,
index d98d43f80958b87acbb4f9ea84a421d0d17eb7a5..2def33b1491fbf1d29fae45926ba9195aa285479 100644 (file)
@@ -17,8 +17,8 @@
  * attempt).
  */
 
-bool __list_add_valid(struct list_head *new, struct list_head *prev,
-                     struct list_head *next)
+bool __list_add_valid_or_report(struct list_head *new, struct list_head *prev,
+                               struct list_head *next)
 {
        if (CHECK_DATA_CORRUPTION(prev == NULL,
                        "list_add corruption. prev is NULL.\n") ||
@@ -37,9 +37,9 @@ bool __list_add_valid(struct list_head *new, struct list_head *prev,
 
        return true;
 }
-EXPORT_SYMBOL(__list_add_valid);
+EXPORT_SYMBOL(__list_add_valid_or_report);
 
-bool __list_del_entry_valid(struct list_head *entry)
+bool __list_del_entry_valid_or_report(struct list_head *entry)
 {
        struct list_head *prev, *next;
 
@@ -65,6 +65,5 @@ bool __list_del_entry_valid(struct list_head *entry)
                return false;
 
        return true;
-
 }
-EXPORT_SYMBOL(__list_del_entry_valid);
+EXPORT_SYMBOL(__list_del_entry_valid_or_report);