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:
Andrei Vagin 2026-05-06 02:21:33 +00:00 committed by Alexander Mikhalitsyn
parent 5039458f63
commit 2c9ee0abd2

View file

@ -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;
INIT_LIST_HEAD(&end_vma.list);
/* Both lists should not be empty. */
s_vma = list_first_entry(self_vma_list, struct vma_area, list);
t_vma = list_first_entry(tgt_vma_list, struct vma_area, list);
while (1) {
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) ||
vma_area_is(vma_next(s_vma), VMA_AREA_GUARD)) {
s_vma = &end_vma;
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);
continue;
}
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) ||
vma_area_is(vma_next(t_vma), VMA_AREA_GUARD)) {
t_vma = &end_vma;
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);
continue;
}
return prev_vma_end;