diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2018-08-07 15:24:11 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-08-07 15:24:10 -0700 |
commit | 5143a7f32cba7c21b5c57ecbc09e49f3bb96af19 (patch) | |
tree | e21c2124eddfdb732172a7487981a58b6cca1796 /drivers/char/diag | |
parent | 991119cca5522a5466a2a85c2141176bef3e2f44 (diff) | |
parent | 013254162adc53b12866a9300fdf0a1f0bdb9a0e (diff) |
Merge "diag: Protect md_info structure while reallocation"
Diffstat (limited to 'drivers/char/diag')
-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 befc015cd7d5..7cdb2e36eece 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 6c16d80192c6..95ce30aeb258 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; |