diff options
| author | Kees Cook <keescook@chromium.org> | 2016-08-17 14:42:10 -0700 |
|---|---|---|
| committer | Satya Tangirala <satyat@google.com> | 2018-09-21 14:51:01 -0700 |
| commit | 10c8c8a765f1335c46817d6dbf3e288dd45884df (patch) | |
| tree | 42f6f3f2ddb80528c15f68d868887a9cad4279e2 /include/linux | |
| parent | f0b68d746af4aa4988463b24c6f5d0f97f0aaa82 (diff) | |
UPSTREAM: list: Split list_del() debug checking into separate function
(cherry-picked from 0cd340dcb05c4a43742fe156f36737bb2a321bfd)
Similar to the list_add() debug consolidation, this commit consolidates
the debug checking performed during CONFIG_DEBUG_LIST into a new
__list_del_entry_valid() function, and stops list updates when corruption
is found.
Refactored from same hardening in PaX and Grsecurity.
Change-Id: I9e3b8654ab25f3a196e3336fc4882b73010873e7
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/list.h | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/include/linux/list.h b/include/linux/list.h index eb783a0192bd..d5750f2f1c36 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -32,6 +32,7 @@ static inline void INIT_LIST_HEAD(struct list_head *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); #else static inline bool __list_add_valid(struct list_head *new, struct list_head *prev, @@ -39,6 +40,10 @@ static inline bool __list_add_valid(struct list_head *new, { return true; } +static inline bool __list_del_entry_valid(struct list_head *entry) +{ + return true; +} #endif /* @@ -106,22 +111,20 @@ static inline void __list_del(struct list_head * prev, struct list_head * next) * Note: list_empty() on entry does not return true after this, the entry is * in an undefined state. */ -#ifndef CONFIG_DEBUG_LIST static inline void __list_del_entry(struct list_head *entry) { + if (!__list_del_entry_valid(entry)) + return; + __list_del(entry->prev, entry->next); } static inline void list_del(struct list_head *entry) { - __list_del(entry->prev, entry->next); + __list_del_entry(entry); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } -#else -extern void __list_del_entry(struct list_head *entry); -extern void list_del(struct list_head *entry); -#endif /** * list_replace - replace old entry by new one |
