summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorManoj Prabhu B <bmanoj@codeaurora.org>2018-07-25 15:00:19 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2018-07-31 23:12:42 -0700
commit013254162adc53b12866a9300fdf0a1f0bdb9a0e (patch)
tree157895bb99fb3980eb4062aa45cb8266cb224815 /drivers/char
parent414b079b7f4ba955f4679cd87be64199b4e875c7 (diff)
diag: Protect md_info structure while reallocation
The possibility of md_info structure being accessed simultaneously by two threads is prevented by synchronizing while buffer reallocation for hdlc encoding. Extend the scope of protection to md_info till queueing the write to sdcard. CRs-Fixed: 2279473 Change-Id: I75ddb102adfc6c79f35ed69914c9140cb82894c9 Signed-off-by: Manoj Prabhu B <bmanoj@codeaurora.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/diag/diag_memorydevice.c10
-rw-r--r--drivers/char/diag/diagfwd_peripheral.c16
2 files changed, 20 insertions, 6 deletions
diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c
index aa45c2e7ec7b..fe86aebbe55c 100644
--- a/drivers/char/diag/diag_memorydevice.c
+++ b/drivers/char/diag/diag_memorydevice.c
@@ -164,11 +164,12 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
return -EIO;
}
pid = session_info->pid;
- mutex_unlock(&driver->md_session_lock);
ch = &diag_md[id];
- if (!ch || !ch->md_info_inited)
+ if (!ch || !ch->md_info_inited) {
+ mutex_unlock(&driver->md_session_lock);
return -EINVAL;
+ }
spin_lock_irqsave(&ch->lock, flags);
for (i = 0; i < ch->num_tbl_entries && !found; i++) {
@@ -184,8 +185,10 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
}
spin_unlock_irqrestore(&ch->lock, flags);
- if (found)
+ if (found) {
+ mutex_unlock(&driver->md_session_lock);
return -ENOMEM;
+ }
spin_lock_irqsave(&ch->lock, flags);
for (i = 0; i < ch->num_tbl_entries && !found; i++) {
@@ -198,6 +201,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
}
}
spin_unlock_irqrestore(&ch->lock, flags);
+ mutex_unlock(&driver->md_session_lock);
if (!found) {
pr_err_ratelimited("diag: Unable to find an empty space in table, please reduce logging rate, proc: %d\n",
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index bfdce051d405..d4c49ad40210 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -191,6 +191,7 @@ static int check_bufsize_for_encoding(struct diagfwd_buf_t *buf, uint32_t len)
{
int i, ctx = 0;
uint32_t max_size = 0;
+ unsigned long flags;
unsigned char *temp_buf = NULL;
struct diag_md_info *ch = NULL;
@@ -205,11 +206,16 @@ static int check_bufsize_for_encoding(struct diagfwd_buf_t *buf, uint32_t len)
max_size = MAX_PERIPHERAL_HDLC_BUF_SZ;
}
+ mutex_lock(&driver->md_session_lock);
if (buf->len < max_size) {
if (driver->logging_mode == DIAG_MEMORY_DEVICE_MODE) {
ch = &diag_md[DIAG_LOCAL_PROC];
- for (i = 0; ch != NULL &&
- i < ch->num_tbl_entries; i++) {
+ if (!ch || !ch->md_info_inited) {
+ mutex_unlock(&driver->md_session_lock);
+ return -EINVAL;
+ }
+ spin_lock_irqsave(&ch->lock, flags);
+ for (i = 0; i < ch->num_tbl_entries; i++) {
if (ch->tbl[i].buf == buf->data) {
ctx = ch->tbl[i].ctx;
ch->tbl[i].buf = NULL;
@@ -222,18 +228,22 @@ static int check_bufsize_for_encoding(struct diagfwd_buf_t *buf, uint32_t len)
break;
}
}
+ spin_unlock_irqrestore(&ch->lock, flags);
}
temp_buf = krealloc(buf->data, max_size +
APF_DIAG_PADDING,
GFP_KERNEL);
- if (!temp_buf)
+ if (!temp_buf) {
+ mutex_unlock(&driver->md_session_lock);
return -ENOMEM;
+ }
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
"Reallocated data buffer: %pK with size: %d\n",
temp_buf, max_size);
buf->data = temp_buf;
buf->len = max_size;
}
+ mutex_unlock(&driver->md_session_lock);
}
return buf->len;