Commit b7cd0da9 authored by Pavel Skripkin's avatar Pavel Skripkin Committed by Mauro Carvalho Chehab

media: dvb-usb: fix memory leak in dvb_usb_adapter_init

syzbot reported memory leak in dvb-usb. The problem was
in invalid error handling in dvb_usb_adapter_init().

for (n = 0; n < d->props.num_adapters; n++) {
....
	if ((ret = dvb_usb_adapter_stream_init(adap)) ||
		(ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
		(ret = dvb_usb_adapter_frontend_init(adap))) {
		return ret;
	}
...
	d->num_adapters_initialized++;
...
}

In case of error in dvb_usb_adapter_dvb_init() or
dvb_usb_adapter_dvb_init() d->num_adapters_initialized won't be
incremented, but dvb_usb_adapter_exit() relies on it:

	for (n = 0; n < d->num_adapters_initialized; n++)

So, allocated objects won't be freed.
Signed-off-by: default avatarPavel Skripkin <paskripkin@gmail.com>
Reported-by: syzbot+3c2be7424cea3b932b0e@syzkaller.appspotmail.com
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 3ddcea9f
...@@ -79,11 +79,17 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) ...@@ -79,11 +79,17 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
} }
} }
if ((ret = dvb_usb_adapter_stream_init(adap)) || ret = dvb_usb_adapter_stream_init(adap);
(ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) || if (ret)
(ret = dvb_usb_adapter_frontend_init(adap))) {
return ret; return ret;
}
ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs);
if (ret)
goto dvb_init_err;
ret = dvb_usb_adapter_frontend_init(adap);
if (ret)
goto frontend_init_err;
/* use exclusive FE lock if there is multiple shared FEs */ /* use exclusive FE lock if there is multiple shared FEs */
if (adap->fe_adap[1].fe) if (adap->fe_adap[1].fe)
...@@ -103,6 +109,12 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) ...@@ -103,6 +109,12 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
} }
return 0; return 0;
frontend_init_err:
dvb_usb_adapter_dvb_exit(adap);
dvb_init_err:
dvb_usb_adapter_stream_exit(adap);
return ret;
} }
static int dvb_usb_adapter_exit(struct dvb_usb_device *d) static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
......
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