mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
media_module: mpeg2 vh264: [1/1]
PD#173066 Problem: have some KASAN bug Solution: fixed user-memory-access defect. Verify: Verified S905X Change-Id: Ic4fc16d512d1a7bd14a0df9901ae9e6e201bb8a7 Signed-off-by: Peng Yixin <yixin.peng@amlogic.com>
This commit is contained in:
@@ -6359,9 +6359,7 @@ static int vmh264_user_data_read(struct vdec_s *vdec,
|
||||
}
|
||||
|
||||
}
|
||||
res = (u32)copy_to_user((void *)&puserdata_para->meta_info,
|
||||
(void *)&p_userdata_rec->meta_info,
|
||||
sizeof(p_userdata_rec->meta_info));
|
||||
puserdata_para->meta_info = p_userdata_rec->meta_info;
|
||||
|
||||
if (hw->userdata_info.read_index <= hw->userdata_info.write_index)
|
||||
puserdata_para->meta_info.records_in_que =
|
||||
|
||||
@@ -196,6 +196,10 @@ static struct work_struct reset_work;
|
||||
static struct work_struct set_clk_work;
|
||||
static bool is_reset;
|
||||
|
||||
static DEFINE_MUTEX(userdata_mutex);
|
||||
|
||||
static void vmpeg12_create_userdata_manager(u8 *userdata_buf, int buf_len);
|
||||
|
||||
struct mpeg12_userdata_recored_t {
|
||||
struct userdata_meta_info_t meta_info;
|
||||
u32 rec_start;
|
||||
@@ -758,7 +762,7 @@ static void userdata_push_do_work(struct work_struct *work)
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
|
||||
mutex_lock(&userdata_mutex);
|
||||
if (p_userdata_mgr && ccbuf_phyAddress_virt) {
|
||||
int new_wp;
|
||||
|
||||
@@ -771,6 +775,7 @@ static void userdata_push_do_work(struct work_struct *work)
|
||||
memcpy(head_info, pdata, 8);
|
||||
} else
|
||||
memset(head_info, 0, 8);
|
||||
mutex_unlock(&userdata_mutex);
|
||||
aml_swap_data(head_info, 8);
|
||||
|
||||
wp = (head_info[0] << 8 | head_info[1]);
|
||||
@@ -1272,6 +1277,7 @@ static void reset_do_work(struct work_struct *work)
|
||||
vf_reg_provider(&vmpeg_vf_prov);
|
||||
#endif
|
||||
vmpeg12_prot_init();
|
||||
vmpeg12_create_userdata_manager(ccbuf_phyAddress_virt, CCBUF_SIZE);
|
||||
vmpeg12_reset_userdata_fifo(vdec, 1);
|
||||
#ifdef DUMP_USER_DATA
|
||||
last_wp = 0;
|
||||
@@ -1386,10 +1392,10 @@ int vmpeg12_set_isreset(struct vdec_s *vdec, int isreset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(userdata_mutex);
|
||||
|
||||
|
||||
void vmpeg12_crate_userdata_manager(u8 *userdata_buf, int buf_len)
|
||||
|
||||
static void vmpeg12_create_userdata_manager(u8 *userdata_buf, int buf_len)
|
||||
{
|
||||
mutex_lock(&userdata_mutex);
|
||||
|
||||
@@ -1405,7 +1411,7 @@ void vmpeg12_crate_userdata_manager(u8 *userdata_buf, int buf_len)
|
||||
mutex_unlock(&userdata_mutex);
|
||||
}
|
||||
|
||||
void vmpeg12_destroy_userdata_manager(void)
|
||||
static void vmpeg12_destroy_userdata_manager(void)
|
||||
{
|
||||
mutex_lock(&userdata_mutex);
|
||||
|
||||
@@ -1637,9 +1643,8 @@ static int vmpeg12_user_data_read(struct vdec_s *vdec,
|
||||
}
|
||||
|
||||
}
|
||||
res = (u32)copy_to_user((void *)&puserdata_para->meta_info,
|
||||
(void *)&p_userdata_rec->meta_info,
|
||||
sizeof(p_userdata_rec->meta_info));
|
||||
|
||||
puserdata_para->meta_info = p_userdata_rec->meta_info;
|
||||
|
||||
if (p_userdata_mgr->read_index <= p_userdata_mgr->write_index)
|
||||
puserdata_para->meta_info.records_in_que =
|
||||
@@ -1887,10 +1892,20 @@ static void vmpeg12_local_init(void)
|
||||
|
||||
for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
|
||||
vfbuf_use[i] = 0;
|
||||
|
||||
if (mm_blk_handle) {
|
||||
mutex_lock(&userdata_mutex);
|
||||
if (p_userdata_mgr) {
|
||||
vfree(p_userdata_mgr);
|
||||
p_userdata_mgr = NULL;
|
||||
}
|
||||
if (ccbuf_phyAddress_is_remaped_nocache)
|
||||
iounmap(ccbuf_phyAddress_virt);
|
||||
ccbuf_phyAddress_virt = NULL;
|
||||
ccbuf_phyAddress = 0;
|
||||
ccbuf_phyAddress_is_remaped_nocache = 0;
|
||||
decoder_bmmu_box_free(mm_blk_handle);
|
||||
mm_blk_handle = NULL;
|
||||
mutex_unlock(&userdata_mutex);
|
||||
}
|
||||
|
||||
mm_blk_handle = decoder_bmmu_box_alloc_box(
|
||||
@@ -2045,7 +2060,7 @@ static int amvdec_mpeg12_probe(struct platform_device *pdev)
|
||||
#ifdef DUMP_USER_DATA
|
||||
amvdec_mpeg12_init_userdata_dump();
|
||||
#endif
|
||||
vmpeg12_crate_userdata_manager(ccbuf_phyAddress_virt, CCBUF_SIZE);
|
||||
vmpeg12_create_userdata_manager(ccbuf_phyAddress_virt, CCBUF_SIZE);
|
||||
|
||||
INIT_WORK(&userdata_push_work, userdata_push_do_work);
|
||||
INIT_WORK(¬ify_work, vmpeg12_notify_work);
|
||||
|
||||
@@ -2440,10 +2440,14 @@ static long amstream_ioctl_set_ptr(struct port_priv_s *priv, ulong arg)
|
||||
case AMSTREAM_SET_PTR_AUDIO_INFO:
|
||||
if ((this->type & PORT_TYPE_VIDEO)
|
||||
|| (this->type & PORT_TYPE_AUDIO)) {
|
||||
if (parm.pdata_audio_info != NULL)
|
||||
memcpy((void *)&audio_dec_info,
|
||||
(void *)parm.pdata_audio_info,
|
||||
sizeof(audio_dec_info));
|
||||
if (parm.pdata_audio_info != NULL) {
|
||||
if (copy_from_user
|
||||
((void *)&audio_dec_info, (void *)parm.pdata_audio_info,
|
||||
sizeof(audio_dec_info))) {
|
||||
pr_err("[%s]%d, arg err\n", __func__, __LINE__);
|
||||
r = -EFAULT;
|
||||
}
|
||||
}
|
||||
} else
|
||||
r = -EINVAL;
|
||||
break;
|
||||
@@ -2963,14 +2967,29 @@ static long amstream_do_ioctl_old(struct port_priv_s *priv,
|
||||
|
||||
case AMSTREAM_IOC_UD_BUF_READ:
|
||||
{
|
||||
struct userdata_param_t __user *p_userdata_param;
|
||||
p_userdata_param = (void *)arg;
|
||||
if (this->type & PORT_TYPE_USERDATA) {
|
||||
struct userdata_param_t param;
|
||||
struct userdata_param_t *p_userdata_param;
|
||||
|
||||
p_userdata_param = ¶m;
|
||||
|
||||
if (copy_from_user(p_userdata_param,
|
||||
(void __user *)arg,
|
||||
sizeof(struct userdata_param_t))) {
|
||||
r = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (vdec_read_user_data(NULL,
|
||||
p_userdata_param) == 0) {
|
||||
r = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_to_user((void *)arg,
|
||||
p_userdata_param,
|
||||
sizeof(struct userdata_param_t)))
|
||||
r = -EFAULT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3233,19 +3252,23 @@ static long amstream_ioc_setget_ptr(struct port_priv_s *priv,
|
||||
unsigned int cmd, struct am_ioctl_parm_ptr32 __user *arg)
|
||||
{
|
||||
struct am_ioctl_parm_ptr __user *data;
|
||||
struct am_ioctl_parm_ptr32 __user *data32 = arg;
|
||||
struct am_ioctl_parm_ptr32 param;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(¶m,
|
||||
(void __user *)arg,
|
||||
sizeof(struct am_ioctl_parm_ptr32)))
|
||||
return -EFAULT;
|
||||
|
||||
data = compat_alloc_user_space(sizeof(*data));
|
||||
if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
|
||||
return -EFAULT;
|
||||
|
||||
if (put_user(data32->cmd, &data->cmd) ||
|
||||
put_user(compat_ptr(data32->pointer), &data->pointer) ||
|
||||
put_user(data32->len, &data->len))
|
||||
if (put_user(param.cmd, &data->cmd) ||
|
||||
put_user(compat_ptr(param.pointer), &data->pointer) ||
|
||||
put_user(param.len, &data->len))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
ret = amstream_do_ioctl(priv, cmd, (unsigned long)data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -3259,13 +3282,19 @@ static long amstream_set_sysinfo(struct port_priv_s *priv,
|
||||
struct dec_sysinfo __user *data;
|
||||
struct dec_sysinfo32 __user *data32 = arg;
|
||||
int ret;
|
||||
struct dec_sysinfo32 param;
|
||||
|
||||
if (copy_from_user(¶m,
|
||||
(void __user *)arg,
|
||||
sizeof(struct dec_sysinfo32)))
|
||||
return -EFAULT;
|
||||
|
||||
data = compat_alloc_user_space(sizeof(*data));
|
||||
if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
|
||||
return -EFAULT;
|
||||
if (copy_in_user(data, data32, 7 * sizeof(u32)))
|
||||
return -EFAULT;
|
||||
if (put_user(compat_ptr(data32->param), &data->param))
|
||||
if (put_user(compat_ptr(param.param), &data->param))
|
||||
return -EFAULT;
|
||||
if (copy_in_user(&data->ratio64, &data32->ratio64,
|
||||
sizeof(data->ratio64)))
|
||||
|
||||
Reference in New Issue
Block a user