• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Code taken from an example posted to Red Hat bugzilla #220971
3  *
4  *  Original Author: Kostantin Khorenko from OpenVZ/Virtuozzo
5  *  Munged by Jeff Moyer to incorporate it into the autotest framework.
6  *
7  *  Description: "aio_setup_ring() function initializes info->nr_pages
8  *    variable incorrectly, then this variable can be used in error path
9  *    to free the allocated resources. By this way an unprivileged user
10  *    can crash the node."
11  *
12  *  At the beginning of aio_setup_ring, info->nr_pages is initialized
13  *  to the requested number of pages.  However, it is supposed to
14  *  indicate how many pages are mapped in info->ring_pages.  Thus, if
15  *  the call to do_mmap fails:
16  *
17  *	info->mmap_base = do_mmap(NULL, 0, info->mmap_size,
18  *				  PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
19  *				  0);
20  *	if (IS_ERR((void *)info->mmap_base)) {
21  *		up_write(&ctx->mm->mmap_sem);
22  *		printk("mmap err: %ld\n", -info->mmap_base);
23  *		info->mmap_size = 0;
24  *		aio_free_ring(ctx);    <---------
25  *		return -EAGAIN;
26  *	}
27  *
28  *  we end up calling aio_free_ring with a bogus array and cause an oops.
29  *
30  *  This is a destructive test.
31  */
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <sys/mman.h>
35 #include <errno.h>
36 #include <libgen.h>
37 #include <libaio.h>
38 
main(int argc,char ** argv)39 int main(int __attribute__((unused)) argc, char **argv)
40 {
41 	long res;
42 	io_context_t ctx = (void*) 0;
43 	void* map;
44 
45 	while (1) {
46 		map = mmap(NULL, 100, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
47 			   0, 0);
48 		if (map == MAP_FAILED)
49 			break;
50 		map = mmap(NULL, 100, PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE,
51 			   0, 0);
52 		if (map == MAP_FAILED)
53 			break;
54 	}
55 
56 	res = io_setup(10000, &ctx);
57 	if (res != -ENOMEM) {
58 		printf("%s: Error: io_setup returned %ld, expected -ENOMEM\n",
59 		       basename(argv[0]), res);
60 		return 1;
61 	} else
62 		printf("%s: Success!\n", basename(argv[0]));
63 	return 0;
64 }
65