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

Commit c06a3b91 authored by Hardik Arya's avatar Hardik Arya Committed by Gerrit - the friendly Code Review server
Browse files

diag: Set buffer to NULL after freeing from mempool



Currently we are not marking buffer as NULL after
freeing from mempool, which can cause to double free
when multiple threads are trying to free same mempool
buffer. The patch marks buffer as NULL after freeing.

Change-Id: I47129e38eb68bd50a262a791340add524db80209
Signed-off-by: default avatarHardik Arya <harya@codeaurora.org>
parent 51683be8
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -3122,7 +3122,6 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
		if (buf_entry->buf_type == DCI_BUF_SECONDARY) {
			mutex_lock(&buf_entry->data_mutex);
			diagmem_free(driver, buf_entry->data, POOL_TYPE_DCI);
			buf_entry->data = NULL;
			mutex_unlock(&buf_entry->data_mutex);
			kfree(buf_entry);
			buf_entry = NULL;
@@ -3148,7 +3147,6 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
		if (buf_entry && buf_entry->buf_type == DCI_BUF_SECONDARY) {
			mutex_lock(&buf_entry->data_mutex);
			diagmem_free(driver, buf_entry->data, POOL_TYPE_DCI);
			buf_entry->data = NULL;
			mutex_unlock(&buf_entry->data_mutex);
			mutex_destroy(&buf_entry->data_mutex);
			kfree(buf_entry);
+5 −15
Original line number Diff line number Diff line
@@ -220,12 +220,13 @@ static void diag_drain_apps_data(struct diag_apps_data_t *data)

	err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
			     data->ctxt);
	if (err)
	if (err) {
		diagmem_free(driver, data->buf, POOL_TYPE_HDLC);

	} else {
		data->buf = NULL;
		data->len = 0;
	}
}

void diag_update_user_client_work_fn(struct work_struct *work)
{
@@ -922,7 +923,6 @@ static int diag_copy_dci(char __user *buf, size_t count,
			} else if (buf_entry->buf_type == DCI_BUF_SECONDARY) {
				diagmem_free(driver, buf_entry->data,
					     POOL_TYPE_DCI);
				buf_entry->data = NULL;
				mutex_unlock(&buf_entry->data_mutex);
				kfree(buf_entry);
				continue;
@@ -2874,7 +2874,6 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len,

fail_free_buf:
	diagmem_free(driver, data->buf, POOL_TYPE_HDLC);
	data->buf = NULL;
	data->len = 0;

fail_ret:
@@ -2953,7 +2952,6 @@ static int diag_process_apps_data_non_hdlc(unsigned char *buf, int len,

fail_free_buf:
	diagmem_free(driver, data->buf, POOL_TYPE_HDLC);
	data->buf = NULL;
	data->len = 0;

fail_ret:
@@ -2987,7 +2985,6 @@ static int diag_user_process_dci_data(const char __user *buf, int len)
	err = diag_process_dci_transaction(user_space_data, len);
fail:
	diagmem_free(driver, user_space_data, mempool);
	user_space_data = NULL;
	return err;
}

@@ -3025,7 +3022,6 @@ static int diag_user_process_dci_apps_data(const char __user *buf, int len,
	diag_process_apps_dci_read_data(pkt_type, user_space_data, len);
fail:
	diagmem_free(driver, user_space_data, mempool);
	user_space_data = NULL;
	return err;
}

@@ -3062,7 +3058,6 @@ static int diag_user_process_raw_data(const char __user *buf, int len)
			pr_err("diag: In %s, possible integer underflow, payload size: %d\n",
		       __func__, len);
			diagmem_free(driver, user_space_data, mempool);
			user_space_data = NULL;
			return -EBADMSG;
		}
		len -= sizeof(int);
@@ -3072,7 +3067,6 @@ static int diag_user_process_raw_data(const char __user *buf, int len)
						token_offset)) {
			pr_alert("diag: mask request Invalid\n");
			diagmem_free(driver, user_space_data, mempool);
			user_space_data = NULL;
			return -EFAULT;
		}
	}
@@ -3095,7 +3089,6 @@ static int diag_user_process_raw_data(const char __user *buf, int len)
	}
fail:
	diagmem_free(driver, user_space_data, mempool);
	user_space_data = NULL;
	return ret;
}

@@ -3230,7 +3223,6 @@ static int diag_user_process_apps_data(const char __user *buf, int len,
		pr_alert("diag: In %s, unable to copy data from userspace, err: %d\n",
			 __func__, ret);
		diagmem_free(driver, user_space_data, mempool);
		user_space_data = NULL;
		diag_record_stats(pkt_type, PKT_DROP);
		return -EBADMSG;
	}
@@ -3244,7 +3236,6 @@ static int diag_user_process_apps_data(const char __user *buf, int len,
				 __func__);
		}
		diagmem_free(driver, user_space_data, mempool);
		user_space_data = NULL;

		return 0;
	}
@@ -3262,7 +3253,6 @@ static int diag_user_process_apps_data(const char __user *buf, int len,
	mutex_unlock(&apps_data_mutex);

	diagmem_free(driver, user_space_data, mempool);
	user_space_data = NULL;

	check_drain_timer();

+0 −1
Original line number Diff line number Diff line
@@ -1785,7 +1785,6 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt,
		} else if (peripheral == APPS_DATA) {
			diagmem_free(driver, (unsigned char *)buf,
				     POOL_TYPE_HDLC);
			buf = NULL;
		} else {
			pr_err_ratelimited("diag: Invalid peripheral %d in %s, type: %d\n",
					   peripheral, __func__, type);
+3 −2
Original line number Diff line number Diff line
/* Copyright (c) 2008-2014, 2016-2017 The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2014, 2016-2018 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
@@ -221,8 +221,9 @@ void diagmem_free(struct diagchar_dev *driver, void *buf, int pool_type)
			break;
		}
		spin_lock_irqsave(&mempool->lock, flags);
		if (mempool->count > 0) {
		if (mempool->count > 0 && buf) {
			mempool_free(buf, mempool->pool);
			buf = NULL;
			atomic_add(-1, (atomic_t *)&mempool->count);
		} else {
			pr_err_ratelimited("diag: Attempting to free items from %s mempool which is already empty\n",