mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 21:36:41 +07:00
[media] v4l2-ioctl: Don't assume file->private_data always points to a v4l2_fh
Commit efbceecd45
, adds a number of helper
functions for ctrl related ioctls to v4l2-ioctl.c, these helpers assume that
if file->private_data != NULL, it points to a v4l2_fh, which is only the case
for drivers which actually use v4l2_fh.
This breaks for example bttv which use the "filedata" pointer for its own uses,
and now all the ctrl ioctls try to use whatever its filedata points to as
v4l2_fh and think it has a ctrl_handler, leading to:
[ 142.499214] BUG: unable to handle kernel NULL pointer dereference at 0000000000000021
[ 142.499270] IP: [<ffffffffa01cb959>] v4l2_queryctrl+0x29/0x230 [videodev]
[ 142.514649] [<ffffffffa01c7a77>] v4l_queryctrl+0x47/0x90 [videodev]
[ 142.517417] [<ffffffffa01c58b1>] __video_do_ioctl+0x2c1/0x420 [videodev]
[ 142.520116] [<ffffffffa01c7ee6>] video_usercopy+0x1a6/0x470 [videodev]
...
This patch adds the missing test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) tests
to the ctrl ioctl helpers v4l2_fh paths, fixing the issues with for example
the bttv driver.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
a2f8b84fed
commit
7a3ed2d95e
@ -1486,7 +1486,8 @@ static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
|
|||||||
{
|
{
|
||||||
struct video_device *vfd = video_devdata(file);
|
struct video_device *vfd = video_devdata(file);
|
||||||
struct v4l2_queryctrl *p = arg;
|
struct v4l2_queryctrl *p = arg;
|
||||||
struct v4l2_fh *vfh = fh;
|
struct v4l2_fh *vfh =
|
||||||
|
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
|
||||||
|
|
||||||
if (vfh && vfh->ctrl_handler)
|
if (vfh && vfh->ctrl_handler)
|
||||||
return v4l2_queryctrl(vfh->ctrl_handler, p);
|
return v4l2_queryctrl(vfh->ctrl_handler, p);
|
||||||
@ -1502,7 +1503,8 @@ static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
|
|||||||
{
|
{
|
||||||
struct video_device *vfd = video_devdata(file);
|
struct video_device *vfd = video_devdata(file);
|
||||||
struct v4l2_querymenu *p = arg;
|
struct v4l2_querymenu *p = arg;
|
||||||
struct v4l2_fh *vfh = fh;
|
struct v4l2_fh *vfh =
|
||||||
|
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
|
||||||
|
|
||||||
if (vfh && vfh->ctrl_handler)
|
if (vfh && vfh->ctrl_handler)
|
||||||
return v4l2_querymenu(vfh->ctrl_handler, p);
|
return v4l2_querymenu(vfh->ctrl_handler, p);
|
||||||
@ -1518,7 +1520,8 @@ static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
|
|||||||
{
|
{
|
||||||
struct video_device *vfd = video_devdata(file);
|
struct video_device *vfd = video_devdata(file);
|
||||||
struct v4l2_control *p = arg;
|
struct v4l2_control *p = arg;
|
||||||
struct v4l2_fh *vfh = fh;
|
struct v4l2_fh *vfh =
|
||||||
|
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
|
||||||
struct v4l2_ext_controls ctrls;
|
struct v4l2_ext_controls ctrls;
|
||||||
struct v4l2_ext_control ctrl;
|
struct v4l2_ext_control ctrl;
|
||||||
|
|
||||||
@ -1551,7 +1554,8 @@ static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
|
|||||||
{
|
{
|
||||||
struct video_device *vfd = video_devdata(file);
|
struct video_device *vfd = video_devdata(file);
|
||||||
struct v4l2_control *p = arg;
|
struct v4l2_control *p = arg;
|
||||||
struct v4l2_fh *vfh = fh;
|
struct v4l2_fh *vfh =
|
||||||
|
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
|
||||||
struct v4l2_ext_controls ctrls;
|
struct v4l2_ext_controls ctrls;
|
||||||
struct v4l2_ext_control ctrl;
|
struct v4l2_ext_control ctrl;
|
||||||
|
|
||||||
@ -1579,7 +1583,8 @@ static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
|
|||||||
{
|
{
|
||||||
struct video_device *vfd = video_devdata(file);
|
struct video_device *vfd = video_devdata(file);
|
||||||
struct v4l2_ext_controls *p = arg;
|
struct v4l2_ext_controls *p = arg;
|
||||||
struct v4l2_fh *vfh = fh;
|
struct v4l2_fh *vfh =
|
||||||
|
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
|
||||||
|
|
||||||
p->error_idx = p->count;
|
p->error_idx = p->count;
|
||||||
if (vfh && vfh->ctrl_handler)
|
if (vfh && vfh->ctrl_handler)
|
||||||
@ -1597,7 +1602,8 @@ static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
|
|||||||
{
|
{
|
||||||
struct video_device *vfd = video_devdata(file);
|
struct video_device *vfd = video_devdata(file);
|
||||||
struct v4l2_ext_controls *p = arg;
|
struct v4l2_ext_controls *p = arg;
|
||||||
struct v4l2_fh *vfh = fh;
|
struct v4l2_fh *vfh =
|
||||||
|
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
|
||||||
|
|
||||||
p->error_idx = p->count;
|
p->error_idx = p->count;
|
||||||
if (vfh && vfh->ctrl_handler)
|
if (vfh && vfh->ctrl_handler)
|
||||||
@ -1615,7 +1621,8 @@ static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
|
|||||||
{
|
{
|
||||||
struct video_device *vfd = video_devdata(file);
|
struct video_device *vfd = video_devdata(file);
|
||||||
struct v4l2_ext_controls *p = arg;
|
struct v4l2_ext_controls *p = arg;
|
||||||
struct v4l2_fh *vfh = fh;
|
struct v4l2_fh *vfh =
|
||||||
|
test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
|
||||||
|
|
||||||
p->error_idx = p->count;
|
p->error_idx = p->count;
|
||||||
if (vfh && vfh->ctrl_handler)
|
if (vfh && vfh->ctrl_handler)
|
||||||
|
Loading…
Reference in New Issue
Block a user