Commit b6386369 authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Pavel Emelyanov

aio: Add aio sanity checks

Check nr in aio header during dump and correctness of
tail, head and nr during restore.
Signed-off-by: 's avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 3a7968d4
...@@ -99,6 +99,7 @@ int parasite_collect_aios(struct parasite_ctl *ctl, struct vm_area_list *vmas) ...@@ -99,6 +99,7 @@ int parasite_collect_aios(struct parasite_ctl *ctl, struct vm_area_list *vmas)
pr_debug(" `- Ring #%ld @%"PRIx64"\n", pr_debug(" `- Ring #%ld @%"PRIx64"\n",
(long)(pa - &aa->ring[0]), vma->e->start); (long)(pa - &aa->ring[0]), vma->e->start);
pa->ctx = vma->e->start; pa->ctx = vma->e->start;
pa->size = vma->e->end - vma->e->start;
pa->max_reqs = 0; pa->max_reqs = 0;
pa->vma_nr_reqs = &vma->aio_nr_req; pa->vma_nr_reqs = &vma->aio_nr_req;
pa++; pa++;
......
...@@ -139,6 +139,7 @@ struct parasite_dump_posix_timers_args { ...@@ -139,6 +139,7 @@ struct parasite_dump_posix_timers_args {
struct parasite_aio { struct parasite_aio {
unsigned long ctx; unsigned long ctx;
unsigned int size;
unsigned int max_reqs; unsigned int max_reqs;
unsigned int *vma_nr_reqs; unsigned int *vma_nr_reqs;
}; };
......
...@@ -385,12 +385,18 @@ static inline int tty_ioctl(int fd, int cmd, int *arg) ...@@ -385,12 +385,18 @@ static inline int tty_ioctl(int fd, int cmd, int *arg)
#define AIO_RING_COMPAT_FEATURES 1 #define AIO_RING_COMPAT_FEATURES 1
#define AIO_RING_INCOMPAT_FEATURES 0 #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 && return ring->magic == AIO_RING_MAGIC &&
ring->compat_features == AIO_RING_COMPAT_FEATURES && ring->compat_features == AIO_RING_COMPAT_FEATURES &&
ring->incompat_features == AIO_RING_INCOMPAT_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) 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) ...@@ -401,12 +407,13 @@ static int parasite_check_aios(struct parasite_check_aios_args *args)
struct aio_ring *ring; struct aio_ring *ring;
ring = (struct aio_ring *)args->ring[i].ctx; 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_err("Not valid ring #%d\n", i);
pr_info(" `- magic %x\n", ring->magic); pr_info(" `- magic %x\n", ring->magic);
pr_info(" `- cf %d\n", ring->compat_features); pr_info(" `- cf %d\n", ring->compat_features);
pr_info(" `- if %d\n", ring->incompat_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; return -1;
} }
......
...@@ -556,7 +556,7 @@ static unsigned long restore_mapping(const VmaEntry *vma_entry) ...@@ -556,7 +556,7 @@ static unsigned long restore_mapping(const VmaEntry *vma_entry)
*/ */
static int restore_aio_ring(struct rst_aio_ring *raio) 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; int i, maxr, count, fd, ret;
unsigned head = ring->head; unsigned head = ring->head;
unsigned tail = ring->tail; unsigned tail = ring->tail;
...@@ -571,6 +571,15 @@ static int restore_aio_ring(struct rst_aio_ring *raio) ...@@ -571,6 +571,15 @@ static int restore_aio_ring(struct rst_aio_ring *raio)
return -1; 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) if (tail == 0 && head == 0)
goto populate; goto populate;
......
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