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

Commit 1c29f2f1 authored by Hardik Arya's avatar Hardik Arya
Browse files

diag: Mark global buffer NULL after freeing from mempool



Currently we are not marking buffer as NULL after freeing
from mempool which is causing double free of data buffer.
The patch marks global hdlc and non_hdlc data buffer as
NULL after freeing it from mempool.

Change-Id: I5f389cfbb981a6e5d0c880c2112f7e4cf2cae433
Signed-off-by: default avatarHardik Arya <harya@codeaurora.org>
parent c93d9386
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -719,6 +719,16 @@ extern struct diagchar_dev *driver;
extern int wrap_enabled;
extern uint16_t wrap_count;

struct diag_apps_data_t {
	void *buf;
	uint32_t len;
	int ctxt;
	uint8_t allocated;
};

extern struct diag_apps_data_t hdlc_data;
extern struct diag_apps_data_t non_hdlc_data;

void diag_get_timestamp(char *time_str);
void check_drain_timer(void);
int diag_get_remote(int remote_info);
+37 −15
Original line number Diff line number Diff line
@@ -152,14 +152,8 @@ static int timer_in_progress;
static int diag_mask_clear_param = 1;
module_param(diag_mask_clear_param, int, 0644);

struct diag_apps_data_t {
	void *buf;
	uint32_t len;
	int ctxt;
};

static struct diag_apps_data_t hdlc_data;
static struct diag_apps_data_t non_hdlc_data;
struct diag_apps_data_t hdlc_data;
struct diag_apps_data_t non_hdlc_data;
static struct mutex apps_data_mutex;

#define DIAGPKT_MAX_DELAYED_RSP 0xFFFF
@@ -228,6 +222,7 @@ static void diag_drain_apps_data(struct diag_apps_data_t *data)
		diagmem_free(driver, data->buf, POOL_TYPE_HDLC);
	data->buf = NULL;
	data->len = 0;
	data->allocated = 0;
	spin_unlock_irqrestore(&driver->diagmem_lock, flags);
}

@@ -2922,14 +2917,19 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len,
	send.last = (void *)(buf + len - 1);
	send.terminate = 1;

	if (!data->buf)
	if (!data->buf) {
		spin_lock_irqsave(&driver->diagmem_lock, flags);
		data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE +
					APF_DIAG_PADDING,
					  POOL_TYPE_HDLC);
		if (!data->buf) {
			ret = PKT_DROP;
			spin_unlock_irqrestore(&driver->diagmem_lock, flags);
			goto fail_ret;
		}
		data->allocated = 1;
		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
	}

	if ((DIAG_MAX_HDLC_BUF_SIZE - data->len) <= max_encoded_size) {
		err = diag_mux_write(DIAG_LOCAL_PROC, data->buf, data->len,
@@ -2940,13 +2940,17 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len,
		}
		data->buf = NULL;
		data->len = 0;
		spin_lock_irqsave(&driver->diagmem_lock, flags);
		data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE +
					APF_DIAG_PADDING,
					  POOL_TYPE_HDLC);
		if (!data->buf) {
			ret = PKT_DROP;
			spin_unlock_irqrestore(&driver->diagmem_lock, flags);
			goto fail_ret;
		}
		data->allocated = 1;
		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
	}

	enc.dest = data->buf + data->len;
@@ -2969,13 +2973,17 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len,
		}
		data->buf = NULL;
		data->len = 0;
		spin_lock_irqsave(&driver->diagmem_lock, flags);
		data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE +
					APF_DIAG_PADDING,
					 POOL_TYPE_HDLC);
		if (!data->buf) {
			ret = PKT_DROP;
			spin_unlock_irqrestore(&driver->diagmem_lock, flags);
			goto fail_ret;
		}
		data->allocated = 1;
		spin_unlock_irqrestore(&driver->diagmem_lock, flags);

		enc.dest = data->buf + data->len;
		enc.dest_last = (void *)(data->buf + data->len +
@@ -3003,9 +3011,11 @@ static int diag_process_apps_data_hdlc(unsigned char *buf, int len,

fail_free_buf:
	spin_lock_irqsave(&driver->diagmem_lock, flags);
	if (data->allocated)
		diagmem_free(driver, data->buf, POOL_TYPE_HDLC);
	data->buf = NULL;
	data->len = 0;
	data->allocated = 0;
	spin_unlock_irqrestore(&driver->diagmem_lock, flags);
fail_ret:
	return ret;
@@ -3033,13 +3043,17 @@ static int diag_process_apps_data_non_hdlc(unsigned char *buf, int len,
	}

	if (!data->buf) {
		spin_lock_irqsave(&driver->diagmem_lock, flags);
		data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE +
					APF_DIAG_PADDING,
					  POOL_TYPE_HDLC);
		if (!data->buf) {
			ret = PKT_DROP;
			spin_unlock_irqrestore(&driver->diagmem_lock, flags);
			goto fail_ret;
		}
		data->allocated = 1;
		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
	}

	if ((DIAG_MAX_HDLC_BUF_SIZE - data->len) <= max_pkt_size) {
@@ -3051,13 +3065,17 @@ static int diag_process_apps_data_non_hdlc(unsigned char *buf, int len,
		}
		data->buf = NULL;
		data->len = 0;
		spin_lock_irqsave(&driver->diagmem_lock, flags);
		data->buf = diagmem_alloc(driver, DIAG_MAX_HDLC_BUF_SIZE +
					APF_DIAG_PADDING,
					POOL_TYPE_HDLC);
		if (!data->buf) {
			ret = PKT_DROP;
			spin_unlock_irqrestore(&driver->diagmem_lock, flags);
			goto fail_ret;
		}
		data->allocated = 1;
		spin_unlock_irqrestore(&driver->diagmem_lock, flags);
	}

	header.start = CONTROL_CHAR;
@@ -3084,9 +3102,11 @@ static int diag_process_apps_data_non_hdlc(unsigned char *buf, int len,

fail_free_buf:
	spin_lock_irqsave(&driver->diagmem_lock, flags);
	if (data->allocated)
		diagmem_free(driver, data->buf, POOL_TYPE_HDLC);
	data->buf = NULL;
	data->len = 0;
	data->allocated = 0;
	spin_unlock_irqrestore(&driver->diagmem_lock, flags);
fail_ret:
	return ret;
@@ -4149,8 +4169,10 @@ static int __init diagchar_init(void)
	driver->rsp_buf_ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_CMD, TYPE_CMD);
	hdlc_data.ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_DATA, 1);
	hdlc_data.len = 0;
	hdlc_data.allocated = 0;
	non_hdlc_data.ctxt = SET_BUF_CTXT(APPS_DATA, TYPE_DATA, 1);
	non_hdlc_data.len = 0;
	non_hdlc_data.allocated = 0;
	mutex_init(&driver->hdlc_disable_mutex);
	mutex_init(&driver->diagchar_mutex);
	mutex_init(&driver->diag_notifier_mutex);
+14 −3
Original line number Diff line number Diff line
@@ -1766,6 +1766,7 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt,
	int peripheral = -1;
	int type = -1;
	int num = -1;
	struct diag_apps_data_t *temp = NULL;

	if (!buf || len < 0)
		return -EINVAL;
@@ -1784,9 +1785,19 @@ static int diagfwd_mux_write_done(unsigned char *buf, int len, int buf_ctxt,
			diag_ws_on_copy(DIAG_WS_MUX);
		} else if (peripheral == APPS_DATA) {
			spin_lock_irqsave(&driver->diagmem_lock, flags);
			diagmem_free(driver, (unsigned char *)buf,
				     POOL_TYPE_HDLC);
			buf = NULL;
			if (hdlc_data.allocated)
				temp = &hdlc_data;
			else if (non_hdlc_data.allocated)
				temp = &non_hdlc_data;
			else
				DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
				"No apps data buffer is allocated to be freed\n");
			if (temp) {
				diagmem_free(driver, temp->buf, POOL_TYPE_HDLC);
				temp->buf = NULL;
				temp->len = 0;
				temp->allocated = 0;
			}
			spin_unlock_irqrestore(&driver->diagmem_lock, flags);
		} else {
			pr_err_ratelimited("diag: Invalid peripheral %d in %s, type: %d\n",