Commit 4bb7be96 authored by yang.zhang's avatar yang.zhang Committed by Andrew Morton

kexec: copy only happens before uchunk goes to zero

When loading segments, ubytes is <= mbytes.  When ubytes is exhausted,
there could be remaining mbytes.  Then in the while loop, the buf pointer
advancing with mchunk will causing meaningless reading even though it
doesn't harm.

So let's change to make sure that all of the copying and the rest only
happens before uchunk goes to zero.

Link: https://lkml.kernel.org/r/20240222092119.5602-1-gaoshanliukou@163.comSigned-off-by: default avataryang.zhang <yang.zhang@hexintek.com>
Acked-by: default avatarBaoquan He <bhe@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent a436184e
......@@ -800,22 +800,24 @@ static int kimage_load_normal_segment(struct kimage *image,
PAGE_SIZE - (maddr & ~PAGE_MASK));
uchunk = min(ubytes, mchunk);
/* For file based kexec, source pages are in kernel memory */
if (image->file_mode)
memcpy(ptr, kbuf, uchunk);
else
result = copy_from_user(ptr, buf, uchunk);
if (uchunk) {
/* For file based kexec, source pages are in kernel memory */
if (image->file_mode)
memcpy(ptr, kbuf, uchunk);
else
result = copy_from_user(ptr, buf, uchunk);
ubytes -= uchunk;
if (image->file_mode)
kbuf += uchunk;
else
buf += uchunk;
}
kunmap_local(ptr);
if (result) {
result = -EFAULT;
goto out;
}
ubytes -= uchunk;
maddr += mchunk;
if (image->file_mode)
kbuf += mchunk;
else
buf += mchunk;
mbytes -= mchunk;
cond_resched();
......@@ -866,11 +868,18 @@ static int kimage_load_crash_segment(struct kimage *image,
memset(ptr + uchunk, 0, mchunk - uchunk);
}
/* For file based kexec, source pages are in kernel memory */
if (image->file_mode)
memcpy(ptr, kbuf, uchunk);
else
result = copy_from_user(ptr, buf, uchunk);
if (uchunk) {
/* For file based kexec, source pages are in kernel memory */
if (image->file_mode)
memcpy(ptr, kbuf, uchunk);
else
result = copy_from_user(ptr, buf, uchunk);
ubytes -= uchunk;
if (image->file_mode)
kbuf += uchunk;
else
buf += uchunk;
}
kexec_flush_icache_page(page);
kunmap_local(ptr);
arch_kexec_pre_free_pages(page_address(page), 1);
......@@ -878,12 +887,7 @@ static int kimage_load_crash_segment(struct kimage *image,
result = -EFAULT;
goto out;
}
ubytes -= uchunk;
maddr += mchunk;
if (image->file_mode)
kbuf += mchunk;
else
buf += mchunk;
mbytes -= mchunk;
cond_resched();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment