Skip to content
This repository has been archived by the owner on May 1, 2020. It is now read-only.

Commit

Permalink
msm: vidc: Protect debug_buffer access in core_info_read with lock.
Browse files Browse the repository at this point in the history
Serialize core_info_read with lock so that multiple concurrent
threads do not cause the write to overflow. Also have the bound
check to avoid overflow in write_str function.

CRs-Fixed: 2013361
Change-Id: Ia18a4b94cafd69af1d367861f2499fc202f18e9f
Signed-off-by: Abdulla Anam <abdullahanam@codeaurora.org>
Signed-off-by: Sanjay Singh <sisanj@codeaurora.org>
  • Loading branch information
Abdulla Anam authored and Gerrit - the friendly Code Review server committed Apr 15, 2017
1 parent 61d72ed commit 3a51e00
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
5 changes: 4 additions & 1 deletion drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -734,6 +734,8 @@ static int __init msm_vidc_init(void)
if (rc) {
dprintk(VIDC_ERR,
"Failed to register platform driver\n");
msm_vidc_debugfs_deinit_drv();
debugfs_remove_recursive(vidc_driver->debugfs_root);
kfree(vidc_driver);
vidc_driver = NULL;
}
Expand All @@ -744,6 +746,7 @@ static int __init msm_vidc_init(void)
static void __exit msm_vidc_exit(void)
{
platform_driver_unregister(&msm_vidc_driver);
msm_vidc_debugfs_deinit_drv();
debugfs_remove_recursive(vidc_driver->debugfs_root);
kfree(vidc_driver);
vidc_driver = NULL;
Expand Down
37 changes: 31 additions & 6 deletions drivers/media/platform/msm/vidc/msm_vidc_debug.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -31,6 +31,7 @@ u32 msm_vidc_firmware_unload_delay = 15000;
int msm_vidc_thermal_mitigation_disabled = 0x0;

struct debug_buffer {
struct mutex lock;
char ptr[MAX_DBG_BUF_SIZE];
char *curr;
u32 filled_size;
Expand All @@ -57,8 +58,12 @@ static u32 write_str(struct debug_buffer *buffer, const char *fmt, ...)
{
va_list args;
u32 size;

char *curr = buffer->curr;
char *end = buffer->ptr + MAX_DBG_BUF_SIZE;

va_start(args, fmt);
size = vscnprintf(buffer->curr, MAX_DBG_BUF_SIZE - 1, fmt, args);
size = vscnprintf(curr, end - curr, fmt, args);
va_end(args);
buffer->curr += size;
buffer->filled_size += size;
Expand All @@ -72,12 +77,15 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
struct hfi_device *hdev;
struct hal_fw_info fw_info;
int i = 0, rc = 0;
ssize_t len = 0;

if (!core || !core->device) {
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core);
return 0;
}
hdev = core->device;

mutex_lock(&dbg_buf.lock);
INIT_DBG_BUF(dbg_buf);
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "CORE %d: 0x%pK\n", core->id, core);
Expand All @@ -101,8 +109,11 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
"pending" : "done");
}
return simple_read_from_buffer(buf, count, ppos,
len = simple_read_from_buffer(buf, count, ppos,
dbg_buf.ptr, dbg_buf.filled_size);

mutex_unlock(&dbg_buf.lock);
return len;
}

static const struct file_operations core_info_fops = {
Expand Down Expand Up @@ -139,7 +150,10 @@ static const struct file_operations ssr_fops = {

struct dentry *msm_vidc_debugfs_init_drv(void)
{
struct dentry *dir = debugfs_create_dir("msm_vidc", NULL);
struct dentry *dir = NULL;

mutex_init(&dbg_buf.lock);
dir = debugfs_create_dir("msm_vidc", NULL);
if (IS_ERR_OR_NULL(dir)) {
dir = NULL;
goto failed_create_dir;
Expand Down Expand Up @@ -238,6 +252,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
goto failed_create_dir;
}

if (!debugfs_create_file("info", S_IRUGO, dir, core, &core_info_fops)) {
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
goto failed_create_dir;
Expand Down Expand Up @@ -291,10 +306,14 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
{
struct msm_vidc_inst *inst = file->private_data;
int i, j;
ssize_t len = 0;

if (!inst) {
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", inst);
return 0;
}

mutex_lock(&dbg_buf.lock);
INIT_DBG_BUF(dbg_buf);
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "INSTANCE: 0x%pK (%s)\n", inst,
Expand Down Expand Up @@ -351,9 +370,10 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
write_str(&dbg_buf, "FBD Count: %d\n", inst->count.fbd);

publish_unreleased_reference(inst);

return simple_read_from_buffer(buf, count, ppos,
len = simple_read_from_buffer(buf, count, ppos,
dbg_buf.ptr, dbg_buf.filled_size);
mutex_unlock(&dbg_buf.lock);
return len;
}

static const struct file_operations inst_info_fops = {
Expand Down Expand Up @@ -434,3 +454,8 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
}
}

void msm_vidc_debugfs_deinit_drv(void)
{
mutex_destroy(&dbg_buf.lock);
}

3 changes: 2 additions & 1 deletion drivers/media/platform/msm/vidc/msm_vidc_debug.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -123,6 +123,7 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
struct dentry *parent);
void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
enum msm_vidc_debugfs_event e);
void msm_vidc_debugfs_deinit_drv(void);

static inline void tic(struct msm_vidc_inst *i, enum profiling_points p,
char *b)
Expand Down

0 comments on commit 3a51e00

Please sign in to comment.