diff options
| author | Manoj Prabhu B <bmanoj@codeaurora.org> | 2018-07-25 15:00:19 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-07-31 23:12:42 -0700 |
| commit | 013254162adc53b12866a9300fdf0a1f0bdb9a0e (patch) | |
| tree | 157895bb99fb3980eb4062aa45cb8266cb224815 /drivers/char | |
| parent | 414b079b7f4ba955f4679cd87be64199b4e875c7 (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.c | 10 | ||||
| -rw-r--r-- | drivers/char/diag/diagfwd_peripheral.c | 16 |
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; |
