[CRIU] [PATCH v7 5/6] aio: Add aio sanity checks

Kirill Tkhai ktkhai at virtuozzo.com
Mon Mar 28 02:23:47 PDT 2016


Check nr in aio header during dump and correctness of
tail, head and nr during restore.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/aio.c              |    1 +
 criu/include/parasite.h |    1 +
 criu/pie/parasite.c     |   15 +++++++++++----
 criu/pie/restorer.c     |   11 ++++++++++-
 4 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/criu/aio.c b/criu/aio.c
index 5ccf51a..888a640 100644
--- a/criu/aio.c
+++ b/criu/aio.c
@@ -99,6 +99,7 @@ int parasite_collect_aios(struct parasite_ctl *ctl, struct vm_area_list *vmas)
 		pr_debug(" `- Ring #%ld @%"PRIx64"\n",
 				(long)(pa - &aa->ring[0]), vma->e->start);
 		pa->ctx = vma->e->start;
+		pa->size = vma->e->end - vma->e->start;
 		pa->max_reqs = 0;
 		pa->vma_nr_reqs = &vma->aio_nr_req;
 		pa++;
diff --git a/criu/include/parasite.h b/criu/include/parasite.h
index 6ca56f7..341a8e5 100644
--- a/criu/include/parasite.h
+++ b/criu/include/parasite.h
@@ -139,6 +139,7 @@ struct parasite_dump_posix_timers_args {
 
 struct parasite_aio {
 	unsigned long ctx;
+	unsigned int size;
 	unsigned int max_reqs;
 	unsigned int *vma_nr_reqs;
 };
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index d82518e..5b45048 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -385,12 +385,18 @@ static inline int tty_ioctl(int fd, int cmd, int *arg)
 #define AIO_RING_COMPAT_FEATURES	1
 #define AIO_RING_INCOMPAT_FEATURES	0
 
-static int sane_ring(struct aio_ring *ring)
+static int sane_ring(struct parasite_aio *aio)
 {
+	struct aio_ring *ring = (struct aio_ring *)aio->ctx;
+	unsigned nr;
+
+	nr = (aio->size - sizeof(struct aio_ring)) / sizeof(struct io_event);
+
 	return ring->magic == AIO_RING_MAGIC &&
 		ring->compat_features == AIO_RING_COMPAT_FEATURES &&
 		ring->incompat_features == AIO_RING_INCOMPAT_FEATURES &&
-		ring->header_length == sizeof(struct aio_ring);
+		ring->header_length == sizeof(struct aio_ring) &&
+		ring->nr == nr;
 }
 
 static int parasite_check_aios(struct parasite_check_aios_args *args)
@@ -401,12 +407,13 @@ static int parasite_check_aios(struct parasite_check_aios_args *args)
 		struct aio_ring *ring;
 
 		ring = (struct aio_ring *)args->ring[i].ctx;
-		if (!sane_ring(ring)) {
+		if (!sane_ring(&args->ring[i])) {
 			pr_err("Not valid ring #%d\n", i);
 			pr_info(" `- magic %x\n", ring->magic);
 			pr_info(" `- cf    %d\n", ring->compat_features);
 			pr_info(" `- if    %d\n", ring->incompat_features);
-			pr_info(" `- size  %d (%zd)\n", ring->header_length, sizeof(struct aio_ring));
+			pr_info(" `- header size  %d (%zd)\n", ring->header_length, sizeof(struct aio_ring));
+			pr_info(" `- nr    %d\n", ring->nr);
 			return -1;
 		}
 
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index c655705..4fb38a7 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -556,7 +556,7 @@ static unsigned long restore_mapping(const VmaEntry *vma_entry)
  */
 static int restore_aio_ring(struct rst_aio_ring *raio)
 {
-	struct aio_ring *ring = (void *)raio->addr;
+	struct aio_ring *ring = (void *)raio->addr, *new;
 	int i, maxr, count, fd, ret;
 	unsigned head = ring->head;
 	unsigned tail = ring->tail;
@@ -571,6 +571,15 @@ static int restore_aio_ring(struct rst_aio_ring *raio)
 		return -1;
 	}
 
+	new = (struct aio_ring *)ctx;
+	i = (raio->len - sizeof(struct aio_ring)) / sizeof(struct io_event);
+	if (tail >= ring->nr || head >= ring->nr || ring->nr != i ||
+	    new->nr != ring->nr) {
+		pr_err("wrong aio parametrs: tail=%x head=%x nr=%x len=%lx\n",
+			tail, head, raio->nr_req, raio->len);
+		return -1;
+	}
+
 	if (tail == 0 && head == 0)
 		goto populate;
 



More information about the CRIU mailing list