mirror of https://github.com/dynup/kpatch
fix list corruption in special section handlers
The kpatch_regenerate_* functions use a local list_head to construct the
new list. While the local list_head is copied to the sec->relas after
it is built, the neighboring nodes in the list are not updated, leading
to list corruption.
This commit uses list_replace() which updates the neighbor nodes properly.
Regression introduced by PR #117 5d36dd1
.
Fixes #185.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit is contained in:
parent
d55523f624
commit
2b92531df2
|
@ -1029,7 +1029,7 @@ void kpatch_regenerate_bug_table_rela_section(struct kpatch_elf *kelf)
|
|||
}
|
||||
|
||||
/* overwrite with new relas list */
|
||||
sec->relas = newrelas;
|
||||
list_replace(&newrelas, &sec->relas);
|
||||
|
||||
/* include both rela and text sections */
|
||||
sec->include = 1;
|
||||
|
@ -1076,7 +1076,7 @@ void kpatch_regenerate_smp_locks_sections(struct kpatch_elf *kelf)
|
|||
}
|
||||
|
||||
/* overwrite with new relas list */
|
||||
sec->relas = newrelas;
|
||||
list_replace(&newrelas, &sec->relas);
|
||||
|
||||
/* include both rela and text sections */
|
||||
sec->include = 1;
|
||||
|
@ -1141,7 +1141,7 @@ void kpatch_regenerate_parainstructions_sections(struct kpatch_elf *kelf)
|
|||
}
|
||||
|
||||
/* overwrite with new relas table */
|
||||
sec->relas = newrelas;
|
||||
list_replace(&newrelas, &sec->relas);
|
||||
|
||||
/* mark sections for inclusion */
|
||||
sec->include = 1;
|
||||
|
|
|
@ -142,6 +142,22 @@ static inline void list_del(struct list_head *entry)
|
|||
entry->prev = LIST_POISON2;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_replace - replace old entry by new one
|
||||
* @old : the element to be replaced
|
||||
* @new : the new element to insert
|
||||
*
|
||||
* If @old was empty, it will be overwritten.
|
||||
*/
|
||||
static inline void list_replace(struct list_head *old,
|
||||
struct list_head *new)
|
||||
{
|
||||
new->next = old->next;
|
||||
new->next->prev = new;
|
||||
new->prev = old->prev;
|
||||
new->prev->next = new;
|
||||
}
|
||||
|
||||
#define list_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
|
||||
|
|
Loading…
Reference in New Issue