drivers: qcom: ultrasound: check concurrent device open operations

Make opened device count atomic variable to avoid probable race
condition. Race condition leads to memory leak and list corruption.

Change-Id: I4da98f27d36f616bc8fa7b1a848c20cc7eea04e5
Signed-off-by: Divya Ojha <dojha@codeaurora.org>
This commit is contained in:
Divya Ojha 2017-03-30 10:25:15 +05:30 committed by Gerrit - the friendly Code Review server
parent 9b3e8a81dc
commit c57fa14c6a

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -179,7 +179,7 @@ static const int s_button_map[] = {
};
/* The opened devices container */
static int s_opened_devs[MAX_DEVS_NUMBER];
static atomic_t s_opened_devs[MAX_DEVS_NUMBER];
static struct wakeup_source usf_wakeup_source;
@ -2338,14 +2338,11 @@ static uint16_t add_opened_dev(int minor)
uint16_t ind = 0;
for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) {
if (minor == s_opened_devs[ind]) {
if (minor == atomic_cmpxchg(&s_opened_devs[ind], 0, minor)) {
pr_err("%s: device %d is already opened\n",
__func__, minor);
return USF_UNDEF_DEV_ID;
}
if (s_opened_devs[ind] == 0) {
s_opened_devs[ind] = minor;
} else {
pr_debug("%s: device %d is added; ind=%d\n",
__func__, minor, ind);
return ind;
@ -2401,7 +2398,7 @@ static int usf_release(struct inode *inode, struct file *file)
usf_disable(&usf->usf_tx);
usf_disable(&usf->usf_rx);
s_opened_devs[usf->dev_ind] = 0;
atomic_set(&s_opened_devs[usf->dev_ind], 0);
wakeup_source_trash(&usf_wakeup_source);
mutex_unlock(&usf->mutex);