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

Commit d1865b1c authored by Shantanu Jain's avatar Shantanu Jain Committed by Gerrit - the friendly Code Review server
Browse files

input: synaptics_i2c_rmi4: Add check to avoid memory leak



Add conditions to check if fhandler already exists in the list
or not. If exists, then free the memory allocated to the new
fhandler. Otherwise add the fhandler to the list.
Change the location of INIT_LIST_HEAD() call to avoid
memory leak.

CRs-fixed: 575094

This patch is propagated from msm-3.10 kernel
(commit: 89e6a2c4d5b7c9ebeeb190b4f28bff5b2dd95fcb
input: synaptics_i2c_rmi4: Add check to avoid memory leak)

Signed-off-by: default avatarShantanu Jain <shjain@codeaurora.org>
Change-Id: Iaf1429b911baffa53f968c0ca986fec190100ded
parent 81ec4fe4
Loading
Loading
Loading
Loading
+49 −5
Original line number Diff line number Diff line
@@ -2035,6 +2035,30 @@ static int synaptics_rmi4_query_device_info(
	return 0;
}

/*
* This function checks whether the fhandler already existis in the
* support_fn_list or not.
* If it exists then return 1 as found or return 0 as not found.
*
* Called by synaptics_rmi4_query_device().
*/
static int synaptics_rmi4_check_fn_list(struct synaptics_rmi4_data *rmi4_data,
				struct synaptics_rmi4_fn *fhandler)
{
	int found = 0;
	struct synaptics_rmi4_fn *new_fhandler;
	struct synaptics_rmi4_device_info *rmi;

	rmi = &(rmi4_data->rmi4_mod_info);

	if (!list_empty(&rmi->support_fn_list))
		list_for_each_entry(new_fhandler, &rmi->support_fn_list, link)
			if (new_fhandler->fn_number == fhandler->fn_number)
				found = 1;

	return found;
}

 /**
 * synaptics_rmi4_query_device()
 *
@@ -2050,7 +2074,7 @@ static int synaptics_rmi4_query_device_info(
 */
static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;
	int retval, found;
	unsigned char ii;
	unsigned char page_number;
	unsigned char intr_count = 0;
@@ -2064,8 +2088,6 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)

	rmi = &(rmi4_data->rmi4_mod_info);

	INIT_LIST_HEAD(&rmi->support_fn_list);

	/* Scan the page description tables of the pages to service */
	for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
		for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
@@ -2080,7 +2102,7 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
				return retval;

			fhandler = NULL;

			found = 0;
			if (rmi_fd.fn_number == 0) {
				dev_dbg(&rmi4_data->i2c_client->dev,
						"%s: Reached end of PDT\n",
@@ -2201,8 +2223,28 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
			intr_count += (rmi_fd.intr_src_count & MASK_3BIT);

			if (fhandler && rmi_fd.intr_src_count) {
				/* Want to check whether the fhandler already
				exists in the support_fn_list or not.
				If not found then add it to the list, otherwise
				free the memory allocated to it.
				*/
				found = synaptics_rmi4_check_fn_list(rmi4_data,
						fhandler);

				if (!found) {
					list_add_tail(&fhandler->link,
						&rmi->support_fn_list);
				} else {
					if (fhandler->fn_number ==
							SYNAPTICS_RMI4_F1A) {
						synaptics_rmi4_f1a_kfree(
							fhandler);
					} else {
						kfree(fhandler->data);
						kfree(fhandler->extra);
					}
					kfree(fhandler);
				}
			}
		}
	}
@@ -2829,6 +2871,8 @@ static int synaptics_rmi4_probe(struct i2c_client *client,
	init_waitqueue_head(&rmi4_data->wait);
	mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex));

	INIT_LIST_HEAD(&rmi->support_fn_list);

	retval = synaptics_rmi4_query_device(rmi4_data);
	if (retval < 0) {
		dev_err(&client->dev,