Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb2291af authored by Azhar Shaikh's avatar Azhar Shaikh
Browse files

usb: android: Fix crash on composition switch from ncm



On composition switch from a ncm composition to any other
composition below call stack is seen

[<ffffffc00031cc1c>] __list_del_entry+0x74/0xd8
[<ffffffc00031cc90>] list_del+0x10/0x38
[<ffffffc000641154>] usb_remove_function+0x34/0x58
[<ffffffc000673330>] ncm_function_unbind_config+0x1c/0x28
[<ffffffc00067424c>] android_unbind_config+0x4c/0x70
[<ffffffc000642200>] unbind_config.isra.8+0xd0/0xec
[<ffffffc000643984>] usb_remove_config+0x80/0x94
[<ffffffc000672eb8>] android_disable+0x74/0x94
[<ffffffc000673054>] enable_store+0x17c/0x250
[<ffffffc000500400>] dev_attr_store+0x1c/0x28
[<ffffffc0001fe0d4>] sysfs_kf_write+0x40/0x4c
[<ffffffc0001fd3fc>] kernfs_fop_write+0xfc/0x144
[<ffffffc00019f298>] vfs_write+0xb8/0x194

unbind_config() extracts each member from the functions list and calls
unbind_config() callback of that particular function driver. Also before
calling the unbind() callback it deletes this function from the function
list.
ncm_function_unbind_config() calls usb_remove_function() which again tries
to delete the ncm function from the function list and this leads to a
crash.
Fix this by instantiating the ncm function in ncm_function_bind_config()
and de-instantiating in ncm_function_unbind_config().

Change-Id: I649e36e3b48b5db1795cd37edff3af25a6330450
Signed-off-by: default avatarAzhar Shaikh <azhars@codeaurora.org>
parent d2d9da7c
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -1031,10 +1031,6 @@ ncm_function_init(struct android_usb_function *f, struct usb_composite_dev *c)

	f->config = config;

	config->fi = usb_get_function_instance("ncm");
	if (IS_ERR(config->fi))
		return PTR_ERR(config->fi);

	return 0;
}

@@ -1067,6 +1063,10 @@ ncm_function_bind_config(struct android_usb_function *f,
		ncm->ethaddr[0], ncm->ethaddr[1], ncm->ethaddr[2],
		ncm->ethaddr[3], ncm->ethaddr[4], ncm->ethaddr[5]);

	ncm->fi = usb_get_function_instance("ncm");
	if (IS_ERR(ncm->fi))
		return PTR_ERR(ncm->fi);

	ncm_opts = container_of(ncm->fi, struct f_ncm_opts, func_inst);
	strlcpy(ncm_opts->net->name, "ncm%d", sizeof(ncm_opts->net->name));

@@ -1099,8 +1099,8 @@ static void ncm_function_unbind_config(struct android_usb_function *f,
						struct usb_configuration *c)
{
	struct ncm_function_config *ncm = f->config;
	if (ncm->func)
		usb_remove_function(c, ncm->func);

	usb_put_function_instance(ncm->fi);
}

static ssize_t ncm_ethaddr_show(struct device *dev,