Skip to content

Commit 6563368

Browse files
lucvoosparsecli
authored andcommitted
make ptrlist walking against robust against empty blocks
Not all macros or function involved in the ptrlist walking can handle a ptrlist containing some empty blocks. Fix this by: - add the proper check & looping to first & last_ptr_list(). - add a safe version of PTR_ENTRY doing the needed check & looping. - use this safe version for DO_PREPARE() & DO_RESET() Suggested-by: Linus Torvalds <[email protected]> CC: Dan Carpenter <[email protected]> Signed-off-by: Luc Van Oostenryck <[email protected]> Tested-by: Luc Van Oostenryck <[email protected]> Signed-off-by: Christopher Li <[email protected]>
1 parent 0e91f87 commit 6563368

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

ptrlist.h

+26-3
Original file line numberDiff line numberDiff line change
@@ -67,28 +67,51 @@ extern int linearize_ptr_list(struct ptr_list *, void **, int);
6767

6868
static inline void *first_ptr_list(struct ptr_list *list)
6969
{
70+
struct ptr_list *head = list;
71+
7072
if (!list)
7173
return NULL;
74+
75+
while (list->nr == 0) {
76+
list = list->next;
77+
if (list == head)
78+
return NULL;
79+
}
7280
return PTR_ENTRY(list, 0);
7381
}
7482

7583
static inline void *last_ptr_list(struct ptr_list *list)
7684
{
85+
struct ptr_list *head = list;
7786

7887
if (!list)
7988
return NULL;
8089
list = list->prev;
90+
while (list->nr == 0) {
91+
if (list == head)
92+
return NULL;
93+
list = list->prev;
94+
}
8195
return PTR_ENTRY(list, list->nr-1);
8296
}
8397

98+
#define PTR_DEREF(__head, idx, PTR_ENTRY) ({ \
99+
struct ptr_list *__list = __head; \
100+
while (__list && __list->nr == 0) { \
101+
__list = __list->next; \
102+
if (__list == __head) \
103+
__list = NULL; \
104+
} \
105+
__list ? PTR_ENTRY(__list, idx) : NULL; \
106+
})
107+
84108
#define DO_PREPARE(head, ptr, __head, __list, __nr, PTR_ENTRY) \
85109
do { \
86110
struct ptr_list *__head = (struct ptr_list *) (head); \
87111
struct ptr_list *__list = __head; \
88112
int __nr = 0; \
89113
CHECK_TYPE(head,ptr); \
90-
if (__head) ptr = PTR_ENTRY(__head, 0); \
91-
else ptr = NULL
114+
ptr = PTR_DEREF(__head, 0, PTR_ENTRY); \
92115

93116
#define DO_NEXT(ptr, __head, __list, __nr, PTR_ENTRY) \
94117
if (ptr) { \
@@ -110,7 +133,7 @@ static inline void *last_ptr_list(struct ptr_list *list)
110133
do { \
111134
__nr = 0; \
112135
__list = __head; \
113-
if (__head) ptr = PTR_ENTRY(__head, 0); \
136+
if (__head) ptr = PTR_DEREF(__head, 0, PTR_ENTRY); \
114137
} while (0)
115138

116139
#define DO_FINISH(ptr, __head, __list, __nr) \

0 commit comments

Comments
 (0)