diff options
| author | Kees Cook <keescook@chromium.org> | 2016-08-17 14:42:08 -0700 |
|---|---|---|
| committer | Satya Tangirala <satyat@google.com> | 2018-09-21 14:50:33 -0700 |
| commit | 68e051d4a782767639205e447c083d08c51bc028 (patch) | |
| tree | 51e6d7ae514c9dc3c4dfdd0251b82671cc90ade8 /include/linux | |
| parent | cb28adba1a09a8efafb63dcb69c6dfca7e2d7c99 (diff) | |
BACKPORT: list: Split list_add() debug checking into separate function
(cherry-picked from d7c816733d501b59dbdc2483f2cc8e4431fd9160)
Right now, __list_add() code is repeated either in list.h or in
list_debug.c, but the only differences between the two versions
are the debug checks. This commit therefore extracts these debug
checks into a separate __list_add_valid() function and consolidates
__list_add(). Additionally this new __list_add_valid() function will stop
list manipulations if a corruption is detected, instead of allowing for
further corruption that may lead to even worse conditions.
This is slight refactoring of the same hardening done in PaX and Grsecurity.
Change-Id: I9a9c9a58857cf837bec7abdb2ee4970cd1242a5e
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 | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/include/linux/list.h b/include/linux/list.h index 993395a2e55c..eb783a0192bd 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -28,27 +28,37 @@ static inline void INIT_LIST_HEAD(struct list_head *list) list->prev = list; } +#ifdef CONFIG_DEBUG_LIST +extern bool __list_add_valid(struct list_head *new, + struct list_head *prev, + struct list_head *next); +#else +static inline bool __list_add_valid(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + return true; +} +#endif + /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ -#ifndef CONFIG_DEBUG_LIST static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { + if (!__list_add_valid(new, prev, next)) + return; + next->prev = new; new->next = next; new->prev = prev; prev->next = new; } -#else -extern void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next); -#endif /** * list_add - add a new entry |
