Skip to content

Commit 4bb7be9

Browse files
zhangyang-hxdakpm00
authored andcommitted
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/[email protected] Signed-off-by: yang.zhang <[email protected]> Acked-by: Baoquan He <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent a436184 commit 4bb7be9

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

kernel/kexec_core.c

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -800,22 +800,24 @@ static int kimage_load_normal_segment(struct kimage *image,
800800
PAGE_SIZE - (maddr & ~PAGE_MASK));
801801
uchunk = min(ubytes, mchunk);
802802

803-
/* For file based kexec, source pages are in kernel memory */
804-
if (image->file_mode)
805-
memcpy(ptr, kbuf, uchunk);
806-
else
807-
result = copy_from_user(ptr, buf, uchunk);
803+
if (uchunk) {
804+
/* For file based kexec, source pages are in kernel memory */
805+
if (image->file_mode)
806+
memcpy(ptr, kbuf, uchunk);
807+
else
808+
result = copy_from_user(ptr, buf, uchunk);
809+
ubytes -= uchunk;
810+
if (image->file_mode)
811+
kbuf += uchunk;
812+
else
813+
buf += uchunk;
814+
}
808815
kunmap_local(ptr);
809816
if (result) {
810817
result = -EFAULT;
811818
goto out;
812819
}
813-
ubytes -= uchunk;
814820
maddr += mchunk;
815-
if (image->file_mode)
816-
kbuf += mchunk;
817-
else
818-
buf += mchunk;
819821
mbytes -= mchunk;
820822

821823
cond_resched();
@@ -866,24 +868,26 @@ static int kimage_load_crash_segment(struct kimage *image,
866868
memset(ptr + uchunk, 0, mchunk - uchunk);
867869
}
868870

869-
/* For file based kexec, source pages are in kernel memory */
870-
if (image->file_mode)
871-
memcpy(ptr, kbuf, uchunk);
872-
else
873-
result = copy_from_user(ptr, buf, uchunk);
871+
if (uchunk) {
872+
/* For file based kexec, source pages are in kernel memory */
873+
if (image->file_mode)
874+
memcpy(ptr, kbuf, uchunk);
875+
else
876+
result = copy_from_user(ptr, buf, uchunk);
877+
ubytes -= uchunk;
878+
if (image->file_mode)
879+
kbuf += uchunk;
880+
else
881+
buf += uchunk;
882+
}
874883
kexec_flush_icache_page(page);
875884
kunmap_local(ptr);
876885
arch_kexec_pre_free_pages(page_address(page), 1);
877886
if (result) {
878887
result = -EFAULT;
879888
goto out;
880889
}
881-
ubytes -= uchunk;
882890
maddr += mchunk;
883-
if (image->file_mode)
884-
kbuf += mchunk;
885-
else
886-
buf += mchunk;
887891
mbytes -= mchunk;
888892

889893
cond_resched();

0 commit comments

Comments
 (0)