• Al Viro's avatar
    ioctx_alloc(): fix vma (and file) leak on failure · 18bae5b9
    Al Viro authored
    commit deeb8525 upstream.
    
    If we fail past the aio_setup_ring(), we need to destroy the
    mapping.  We don't need to care about anybody having found ctx,
    or added requests to it, since the last failure exit is exactly
    the failure to make ctx visible to lookups.
    
    Reproducer (based on one by Joe Mario <jmario@redhat.com>):
    
    void count(char *p)
    {
    	char s[80];
    	printf("%s: ", p);
    	fflush(stdout);
    	sprintf(s, "/bin/cat /proc/%d/maps|/bin/fgrep -c '/[aio] (deleted)'", getpid());
    	system(s);
    }
    
    int main()
    {
    	io_context_t *ctx;
    	int created, limit, i, destroyed;
    	FILE *f;
    
    	count("before");
    	if ((f = fopen("/proc/sys/fs/aio-max-nr", "r")) == NULL)
    		perror("opening aio-max-nr");
    	else if (fscanf(f, "%d", &limit) != 1)
    		fprintf(stderr, "can't parse aio-max-nr\n");
    	else if ((ctx = calloc(limit, sizeof(io_context_t))) == NULL)
    		perror("allocating aio_context_t array");
    	else {
    		for (i = 0, created = 0; i < limit; i++) {
    			if (io_setup(1000, ctx + created) == 0)
    				created++;
    		}
    		for (i = 0, destroyed = 0; i < created; i++)
    			if (io_destroy(ctx[i]) == 0)
    				destroyed++;
    		printf("created %d, failed %d, destroyed %d\n",
    			created, limit - created, destroyed);
    		count("after");
    	}
    }
    Found-by: default avatarJoe Mario <jmario@redhat.com>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
    18bae5b9
aio.c 42.6 KB