From: Antonios Motakis Date: Thu, 28 Apr 2016 14:01:29 +0000 (+0200) Subject: driver: fix unsigned long overflow in leave_hypervisor X-Git-Url: http://rtime.felk.cvut.cz/gitweb/jailhouse.git/commitdiff_plain/d2219890eabe7e9132912e45b2c3f3bbea9512fa driver: fix unsigned long overflow in leave_hypervisor When shutting down the hypervisor, in the leave_hypervisor function, the Linux driver touches every hypervisor page, to ensure all pages are mapped. However, the current implementation assumes hv_core_and_percpu_size is aligned to PAGE_SIZE. This may not be the case, if PAGE_SIZE is different on the hypervisor side. This can cause an unsigned long overflow, leading to an infinite loop of touching successive pages starting from hypervisor_mem. The loop will be broken as soon as Linux tries to touch an invalid page, leading to a kernel crash. Signed-off-by: Antonios Motakis Signed-off-by: Jan Kiszka --- diff --git a/driver/main.c b/driver/main.c index 60b67bd..39ab794 100644 --- a/driver/main.c +++ b/driver/main.c @@ -330,15 +330,15 @@ error_unlock: static void leave_hypervisor(void *info) { - unsigned long size; void *page; int err; /* Touch each hypervisor page we may need during the switch so that * the active mm definitely contains all mappings. At least x86 does * not support taking any faults while switching worlds. */ - for (page = hypervisor_mem, size = hv_core_and_percpu_size; size > 0; - size -= PAGE_SIZE, page += PAGE_SIZE) + for (page = hypervisor_mem; + page < hypervisor_mem + hv_core_and_percpu_size; + page += PAGE_SIZE) readl((void __iomem *)page); /* either returns 0 or the same error code across all CPUs */