mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-18 00:58:31 +00:00
restore: update prev_vma_end after processing the last vma in a list
Here is actually two issues: First, prev_vma_end isn't updated properly after processing the last vma in a list. Second, a dummy end_vma isn't fully initialized and vma_area_is can access uninitilized data. Signed-off-by: Andrei Vagin <avagin@google.com>
This commit is contained in:
parent
5039458f63
commit
2c9ee0abd2
1 changed files with 22 additions and 10 deletions
|
|
@ -2487,36 +2487,48 @@ static long restorer_get_vma_hint(struct list_head *tgt_vma_list, struct list_he
|
||||||
end_e.start = end_e.end = kdat.task_size;
|
end_e.start = end_e.end = kdat.task_size;
|
||||||
INIT_LIST_HEAD(&end_vma.list);
|
INIT_LIST_HEAD(&end_vma.list);
|
||||||
|
|
||||||
|
/* Both lists should not be empty. */
|
||||||
s_vma = list_first_entry(self_vma_list, struct vma_area, list);
|
s_vma = list_first_entry(self_vma_list, struct vma_area, list);
|
||||||
t_vma = list_first_entry(tgt_vma_list, struct vma_area, list);
|
t_vma = list_first_entry(tgt_vma_list, struct vma_area, list);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (prev_vma_end + vma_len > s_vma->e->start) {
|
if (prev_vma_end + vma_len > s_vma->e->start) {
|
||||||
|
if (s_vma == &end_vma)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (prev_vma_end < s_vma->e->end)
|
||||||
|
prev_vma_end = s_vma->e->end;
|
||||||
|
/*
|
||||||
|
* VMA_AREA_GUARD entries are synthetic and they are
|
||||||
|
* always after real vma entries.
|
||||||
|
*/
|
||||||
if ((s_vma->list.next == self_vma_list) ||
|
if ((s_vma->list.next == self_vma_list) ||
|
||||||
vma_area_is(vma_next(s_vma), VMA_AREA_GUARD)) {
|
vma_area_is(vma_next(s_vma), VMA_AREA_GUARD)) {
|
||||||
s_vma = &end_vma;
|
s_vma = &end_vma;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (s_vma == &end_vma)
|
|
||||||
break;
|
|
||||||
if (prev_vma_end < s_vma->e->end)
|
|
||||||
prev_vma_end = s_vma->e->end;
|
|
||||||
s_vma = vma_next(s_vma);
|
s_vma = vma_next(s_vma);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_vma_end + vma_len > t_vma->e->start) {
|
if (prev_vma_end + vma_len > t_vma->e->start) {
|
||||||
|
if (t_vma == &end_vma)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (prev_vma_end < t_vma->e->end)
|
||||||
|
prev_vma_end = t_vma->e->end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VMA_AREA_GUARD entries are synthetic and they are
|
||||||
|
* always after real vma entries.
|
||||||
|
*/
|
||||||
if ((t_vma->list.next == tgt_vma_list) ||
|
if ((t_vma->list.next == tgt_vma_list) ||
|
||||||
vma_area_is(vma_next(t_vma), VMA_AREA_GUARD)) {
|
vma_area_is(vma_next(t_vma), VMA_AREA_GUARD)) {
|
||||||
t_vma = &end_vma;
|
t_vma = &end_vma;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (t_vma == &end_vma)
|
|
||||||
break;
|
|
||||||
if (prev_vma_end < t_vma->e->end)
|
|
||||||
prev_vma_end = t_vma->e->end;
|
|
||||||
t_vma = vma_next(t_vma);
|
t_vma = vma_next(t_vma);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return prev_vma_end;
|
return prev_vma_end;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue