提交 8f8366eb 编写于 作者: S Sakari Ailus 提交者: Zheng Zengkai

media: v4l: ioctl: Fix memory leak in video_usercopy

stable inclusion
from stable-5.10.21
commit 5400770e31e8b80efc25b4c1d619361255174d11
bugzilla: 50609

--------------------------------

commit fb18802a upstream.

When an IOCTL with argument size larger than 128 that also used array
arguments were handled, two memory allocations were made but alas, only
the latter one of them was released. This happened because there was only
a single local variable to hold such a temporary allocation.

Fix this by adding separate variables to hold the pointers to the
temporary allocations.
Reported-by: NArnd Bergmann <arnd@kernel.org>
Reported-by: syzbot+1115e79c8df6472c612b@syzkaller.appspotmail.com
Fixes: d14e6d76 ("[media] v4l: Add multi-planar ioctl handling code")
Cc: stable@vger.kernel.org
Signed-off-by: NSakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: NArnd Bergmann <arnd@arndb.de>
Acked-by: NHans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: NLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: NMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 508ec60d
......@@ -3251,7 +3251,7 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
v4l2_kioctl func)
{
char sbuf[128];
void *mbuf = NULL;
void *mbuf = NULL, *array_buf = NULL;
void *parg = (void *)arg;
long err = -EINVAL;
bool has_array_args;
......@@ -3286,20 +3286,14 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
has_array_args = err;
if (has_array_args) {
/*
* When adding new types of array args, make sure that the
* parent argument to ioctl (which contains the pointer to the
* array) fits into sbuf (so that mbuf will still remain
* unused up to here).
*/
mbuf = kvmalloc(array_size, GFP_KERNEL);
array_buf = kvmalloc(array_size, GFP_KERNEL);
err = -ENOMEM;
if (NULL == mbuf)
if (array_buf == NULL)
goto out_array_args;
err = -EFAULT;
if (copy_from_user(mbuf, user_ptr, array_size))
if (copy_from_user(array_buf, user_ptr, array_size))
goto out_array_args;
*kernel_ptr = mbuf;
*kernel_ptr = array_buf;
}
/* Handles IOCTL */
......@@ -3318,7 +3312,7 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
if (has_array_args) {
*kernel_ptr = (void __force *)user_ptr;
if (copy_to_user(user_ptr, mbuf, array_size))
if (copy_to_user(user_ptr, array_buf, array_size))
err = -EFAULT;
goto out_array_args;
}
......@@ -3333,6 +3327,7 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
if (video_put_user((void __user *)arg, parg, orig_cmd))
err = -EFAULT;
out:
kvfree(array_buf);
kvfree(mbuf);
return err;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册