Blame view

lib/list_debug.c 1.8 KB
81f7e3824   Eric Lee   Initial Release, ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  /*
   * Copyright 2006, Red Hat, Inc., Dave Jones
   * Released under the General Public License (GPL).
   *
   * This file contains the linked list validation for DEBUG_LIST.
   */
  
  #include <linux/export.h>
  #include <linux/list.h>
  #include <linux/bug.h>
  #include <linux/kernel.h>
  #include <linux/rculist.h>
  
  /*
   * Check that the data structures for the list manipulations are reasonably
   * valid. Failures here indicate memory corruption (and possibly an exploit
   * attempt).
   */
  
  bool __list_add_valid(struct list_head *new, struct list_head *prev,
  		      struct list_head *next)
  {
  	if (CHECK_DATA_CORRUPTION(next->prev != prev,
  			"list_add corruption. next->prev should be prev (%p), but was %p. (next=%p).
  ",
  			prev, next->prev, next) ||
  	    CHECK_DATA_CORRUPTION(prev->next != next,
  			"list_add corruption. prev->next should be next (%p), but was %p. (prev=%p).
  ",
  			next, prev->next, prev) ||
  	    CHECK_DATA_CORRUPTION(new == prev || new == next,
  			"list_add double add: new=%p, prev=%p, next=%p.
  ",
  			new, prev, next))
  		return false;
  
  	return true;
  }
  EXPORT_SYMBOL(__list_add_valid);
  
  bool __list_del_entry_valid(struct list_head *entry)
  {
  	struct list_head *prev, *next;
  
  	prev = entry->prev;
  	next = entry->next;
  
  	if (CHECK_DATA_CORRUPTION(next == LIST_POISON1,
  			"list_del corruption, %p->next is LIST_POISON1 (%p)
  ",
  			entry, LIST_POISON1) ||
  	    CHECK_DATA_CORRUPTION(prev == LIST_POISON2,
  			"list_del corruption, %p->prev is LIST_POISON2 (%p)
  ",
  			entry, LIST_POISON2) ||
  	    CHECK_DATA_CORRUPTION(prev->next != entry,
  			"list_del corruption. prev->next should be %p, but was %p
  ",
  			entry, prev->next) ||
  	    CHECK_DATA_CORRUPTION(next->prev != entry,
  			"list_del corruption. next->prev should be %p, but was %p
  ",
  			entry, next->prev))
  		return false;
  
  	return true;
  
  }
  EXPORT_SYMBOL(__list_del_entry_valid);