• Al Viro's avatar
    ioctx_alloc(): fix vma (and file) leak on failure · deeb8525
    Al Viro authored
    
    
    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>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    deeb8525