DivestOS/Patches/Linux_CVEs/CVE-2017-8279/ANY/0001.patch
2017-11-07 17:32:46 -05:00

389 lines
13 KiB
Diff

From f09aee50c2ee6b79d94cb42eafc82413968b15cb Mon Sep 17 00:00:00 2001
From: Gopikrishna Mogasati <gmogas@codeaurora.org>
Date: Fri, 5 May 2017 16:04:35 +0530
Subject: diag: Add proper synchronization checks to msg mask table
This fix removes dependency between real time message mask
table and build time message mask table. Also this fix
synchronizes retrieval and modification of real time message
mask table.
CRs-Fixed: 2015227
Change-Id: Id0a0964337ec4645d7061fc35120dfa061a990ff
Signed-off-by: Gopikrishna Mogasati <gmogas@codeaurora.org>
---
drivers/char/diag/diag_masks.c | 65 +++++++++++++++++++++++----------------
drivers/char/diag/diagchar.h | 2 ++
drivers/char/diag/diagchar_core.c | 1 +
drivers/char/diag/diagfwd_cntl.c | 11 ++++---
4 files changed, 49 insertions(+), 30 deletions(-)
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 3c10462..382717b 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -309,10 +309,12 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
return;
-
+ mutex_lock(&driver->msg_mask_lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
- if (!mask->ptr)
+ if (!mask->ptr) {
+ mutex_unlock(&driver->msg_mask_lock);
return;
+ }
buf = mask_info->update_buf;
mutex_lock(&mask_info->lock);
switch (mask_info->status) {
@@ -385,6 +387,7 @@ proceed:
}
err:
mutex_unlock(&mask_info->lock);
+ mutex_unlock(&driver->msg_mask_lock);
}
static void diag_send_time_sync_update(uint8_t peripheral)
@@ -506,7 +509,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
if (!diag_apps_responds())
return 0;
-
+ mutex_lock(&driver->msg_mask_lock);
rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE;
rsp.status = MSG_STATUS_SUCCESS;
@@ -514,7 +517,6 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
rsp.count = driver->msg_mask_tbl_count;
memcpy(dest_buf, &rsp, sizeof(rsp));
write_len += sizeof(rsp);
-
mask_ptr = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask_ptr++) {
if (write_len + sizeof(ssid_range) > dest_len) {
@@ -527,7 +529,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
memcpy(dest_buf + write_len, &ssid_range, sizeof(ssid_range));
write_len += sizeof(ssid_range);
}
-
+ mutex_unlock(&driver->msg_mask_lock);
return write_len;
}
@@ -551,7 +553,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
if (!diag_apps_responds())
return 0;
-
+ mutex_lock(&driver->msg_mask_lock);
req = (struct diag_build_mask_req_t *)src_buf;
rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
rsp.sub_cmd = DIAG_CMD_OP_GET_BUILD_MASK;
@@ -559,9 +561,8 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
rsp.ssid_last = req->ssid_last;
rsp.status = MSG_STATUS_FAIL;
rsp.padding = 0;
-
build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
- for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) {
+ for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
if (build_mask->ssid_first != req->ssid_first)
continue;
num_entries = req->ssid_last - req->ssid_first + 1;
@@ -582,7 +583,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
}
memcpy(dest_buf, &rsp, sizeof(rsp));
write_len += sizeof(rsp);
-
+ mutex_unlock(&driver->msg_mask_lock);
return write_len;
}
@@ -610,6 +611,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
if (!diag_apps_responds())
return 0;
+ mutex_lock(&driver->msg_mask_lock);
req = (struct diag_build_mask_req_t *)src_buf;
rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
rsp.sub_cmd = DIAG_CMD_OP_GET_MSG_MASK;
@@ -617,7 +619,6 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
rsp.ssid_last = req->ssid_last;
rsp.status = MSG_STATUS_FAIL;
rsp.padding = 0;
-
mask = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
if ((req->ssid_first < mask->ssid_first) ||
@@ -635,7 +636,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
}
memcpy(dest_buf, &rsp, sizeof(rsp));
write_len += sizeof(rsp);
-
+ mutex_unlock(&driver->msg_mask_lock);
return write_len;
}
@@ -666,7 +667,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
}
req = (struct diag_msg_build_mask_t *)src_buf;
-
+ mutex_lock(&driver->msg_mask_lock);
mutex_lock(&mask_info->lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -726,7 +727,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
break;
}
mutex_unlock(&mask_info->lock);
-
+ mutex_unlock(&driver->msg_mask_lock);
if (diag_check_update(APPS_DATA))
diag_update_userspace_clients(MSG_MASKS_TYPE);
@@ -779,7 +780,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
}
req = (struct diag_msg_config_rsp_t *)src_buf;
-
+ mutex_lock(&driver->msg_mask_lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
mutex_lock(&mask_info->lock);
mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
@@ -791,6 +792,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
mutex_unlock(&mask->lock);
}
mutex_unlock(&mask_info->lock);
+ mutex_unlock(&driver->msg_mask_lock);
if (diag_check_update(APPS_DATA))
diag_update_userspace_clients(MSG_MASKS_TYPE);
@@ -1294,6 +1296,7 @@ static int diag_create_msg_mask_table(void)
struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr;
struct diag_ssid_range_t range;
+ mutex_lock(&driver->msg_mask_lock);
mutex_lock(&msg_mask.lock);
driver->msg_mask_tbl_count = MSG_MASK_TBL_CNT;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1304,6 +1307,7 @@ static int diag_create_msg_mask_table(void)
break;
}
mutex_unlock(&msg_mask.lock);
+ mutex_unlock(&driver->msg_mask_lock);
return err;
}
@@ -1316,9 +1320,11 @@ static int diag_create_build_time_mask(void)
struct diag_msg_mask_t *build_mask = NULL;
struct diag_ssid_range_t range;
+ mutex_lock(&driver->msg_mask_lock);
mutex_lock(&msg_bt_mask.lock);
+ driver->bt_msg_mask_tbl_count = MSG_MASK_TBL_CNT;
build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
- for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) {
+ for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
range.ssid_first = msg_mask_tbl[i].ssid_first;
range.ssid_last = msg_mask_tbl[i].ssid_last;
err = diag_create_msg_mask_table_entry(build_mask, &range);
@@ -1429,6 +1435,7 @@ static int diag_create_build_time_mask(void)
memcpy(build_mask->ptr, tbl, tbl_size);
}
mutex_unlock(&msg_bt_mask.lock);
+ mutex_unlock(&driver->msg_mask_lock);
return err;
}
@@ -1576,10 +1583,11 @@ static int diag_msg_mask_init(void)
pr_err("diag: Unable to create msg masks, err: %d\n", err);
return err;
}
+ mutex_lock(&driver->msg_mask_lock);
driver->msg_mask = &msg_mask;
-
for (i = 0; i < NUM_PERIPHERALS; i++)
driver->max_ssid_count[i] = 0;
+ mutex_unlock(&driver->msg_mask_lock);
return 0;
}
@@ -1598,7 +1606,7 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE);
if (err)
return err;
-
+ mutex_lock(&driver->msg_mask_lock);
mutex_lock(&dest->lock);
src_mask = (struct diag_msg_mask_t *)src->ptr;
dest_mask = (struct diag_msg_mask_t *)dest->ptr;
@@ -1617,6 +1625,7 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
dest_mask++;
}
mutex_unlock(&dest->lock);
+ mutex_unlock(&driver->msg_mask_lock);
return err;
}
@@ -1628,7 +1637,7 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info)
if (!mask_info)
return;
-
+ mutex_lock(&driver->msg_mask_lock);
mutex_lock(&mask_info->lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1636,7 +1645,7 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info)
mask->ptr = NULL;
}
mutex_unlock(&mask_info->lock);
-
+ mutex_unlock(&driver->msg_mask_lock);
__diag_mask_exit(mask_info);
}
@@ -1644,15 +1653,17 @@ static void diag_msg_mask_exit(void)
{
int i;
struct diag_msg_mask_t *mask = NULL;
-
+ mutex_lock(&driver->msg_mask_lock);
mask = (struct diag_msg_mask_t *)(msg_mask.ptr);
if (mask) {
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++)
kfree(mask->ptr);
kfree(msg_mask.ptr);
+ msg_mask.ptr = NULL;
}
-
kfree(msg_mask.update_buf);
+ msg_mask.update_buf = NULL;
+ mutex_unlock(&driver->msg_mask_lock);
}
static int diag_build_time_mask_init(void)
@@ -1677,13 +1688,15 @@ static void diag_build_time_mask_exit(void)
{
int i;
struct diag_msg_mask_t *mask = NULL;
-
+ mutex_lock(&driver->msg_mask_lock);
mask = (struct diag_msg_mask_t *)(msg_bt_mask.ptr);
if (mask) {
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++)
+ for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, mask++)
kfree(mask->ptr);
- kfree(msg_mask.ptr);
+ kfree(msg_bt_mask.ptr);
+ msg_bt_mask.ptr = NULL;
}
+ mutex_unlock(&driver->msg_mask_lock);
}
static int diag_log_mask_init(void)
@@ -1801,7 +1814,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
return -EIO;
}
mutex_unlock(&driver->diag_maskclear_mutex);
-
+ mutex_lock(&driver->msg_mask_lock);
mutex_lock(&mask_info->lock);
mask = (struct diag_msg_mask_t *)(mask_info->ptr);
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1840,7 +1853,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
total_len += len;
}
mutex_unlock(&mask_info->lock);
-
+ mutex_unlock(&driver->msg_mask_lock);
return err ? err : total_len;
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index b17538a..4047a2c 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -627,8 +627,10 @@ struct diagchar_dev {
struct diag_mask_info *event_mask;
struct diag_mask_info *build_time_mask;
uint8_t msg_mask_tbl_count;
+ uint8_t bt_msg_mask_tbl_count;
uint16_t event_mask_size;
uint16_t last_event_id;
+ struct mutex msg_mask_lock;
/* Variables for Mask Centralization */
uint16_t num_event_id[NUM_PERIPHERALS];
uint32_t num_equip_id[NUM_PERIPHERALS];
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 682c035..afba265 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -3568,6 +3568,7 @@ static int __init diagchar_init(void)
mutex_init(&driver->diag_file_mutex);
mutex_init(&driver->delayed_rsp_mutex);
mutex_init(&apps_data_mutex);
+ mutex_init(&driver->msg_mask_lock);
for (i = 0; i < NUM_PERIPHERALS; i++)
mutex_init(&driver->diagfwd_channel_mutex[i]);
mutex_init(&driver->diagfwd_untag_mutex);
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 82a67f1..729fbf4 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -548,6 +548,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len,
/* Don't account for pkt_id and length */
read_len += header_len - (2 * sizeof(uint32_t));
+ mutex_lock(&driver->msg_mask_lock);
driver->max_ssid_count[peripheral] = header->count;
for (i = 0; i < header->count && read_len < len; i++) {
ssid_range = (struct diag_ssid_range_t *)ptr;
@@ -591,6 +592,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len,
}
driver->msg_mask_tbl_count += 1;
}
+ mutex_unlock(&driver->msg_mask_lock);
}
static void diag_build_time_mask_update(uint8_t *buf,
@@ -615,11 +617,11 @@ static void diag_build_time_mask_update(uint8_t *buf,
__func__, range->ssid_first, range->ssid_last);
return;
}
-
+ mutex_lock(&driver->msg_mask_lock);
build_mask = (struct diag_msg_mask_t *)(driver->build_time_mask->ptr);
num_items = range->ssid_last - range->ssid_first + 1;
- for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) {
+ for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
if (build_mask->ssid_first != range->ssid_first)
continue;
found = 1;
@@ -638,7 +640,7 @@ static void diag_build_time_mask_update(uint8_t *buf,
if (found)
goto end;
- new_size = (driver->msg_mask_tbl_count + 1) *
+ new_size = (driver->bt_msg_mask_tbl_count + 1) *
sizeof(struct diag_msg_mask_t);
temp = krealloc(driver->build_time_mask->ptr, new_size, GFP_KERNEL);
if (!temp) {
@@ -653,8 +655,9 @@ static void diag_build_time_mask_update(uint8_t *buf,
__func__, err);
goto end;
}
- driver->msg_mask_tbl_count += 1;
+ driver->bt_msg_mask_tbl_count += 1;
end:
+ mutex_unlock(&driver->msg_mask_lock);
return;
}
--
cgit v1.1