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

Commit c9e6173b authored by Manu Gautam's avatar Manu Gautam
Browse files

USB: android: Fix synchronization between ffs_enable and ffs_close



FFS function relies on userspace client (or driver) to pass USB
descriptors. It also notifies android composite driver of userspace
client's open and close using android.c's ready and closed callbacks.
Ideally, userspace makes sure to do ffs_close (stop adbd) before moving
to another USB composition which is followed by ffs_open (start adbd).
But, in case of quick composition switch, there is a possibility of
ffs_close and ffs_enable racing with each other. Though there a
protection in place using android_dev->mutex, but closed callback drops
mutex too early. This allows a race between ffs_enable that finds
config->opened as TRUE and enables pull-up, and closed_callback calling
functionfs_unbind. This results in a crash in ffs->set_alt as pull-up
should be allowed only after ffs_open happens.
Since, both ffs_enable/disable and closed/ready_callbacks use same
dev->mutex, we can not enforce ffs_enable to wait until closed_callback
(stop adbd) finishes. Hence, we have to live with this race and fix the
synchronization issue by correcting use of mutex in closed_callback.

Change-Id: I24cdbc55466c97a05341fa9e394f93fd49dd5d5c
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent 82f65cf9
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -631,15 +631,15 @@ static int functionfs_ready_callback(struct ffs_data *ffs)
	struct functionfs_config *config = ffs_function.config;
	int ret = 0;

	/* dev is null in case ADB is not in the composition */
	if (dev) {
		mutex_lock(&dev->mutex);
		ret = functionfs_bind(ffs, dev->cdev);
		if (ret)
		if (ret) {
			mutex_unlock(&dev->mutex);
			return ret;
		}

	/* dev is null in case ADB is not in the composition */
	if (dev)
		mutex_lock(&dev->mutex);
	}

	config->data = ffs;
	config->opened = true;
@@ -675,13 +675,13 @@ static void functionfs_closed_callback(struct ffs_data *ffs)

	config->dev = NULL;

	if (dev)
		mutex_unlock(&dev->mutex);

	config->opened = false;
	config->data = NULL;

	functionfs_unbind(ffs);

	if (dev)
		mutex_unlock(&dev->mutex);
}

static void *functionfs_acquire_dev_callback(const char *dev_name)