Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: v4l2-ctrls-api: fix error handling for v4l2_g_ctrl()

As detected by Coverity, the error check logic at get_ctrl() is
broken: if ptr_to_user() fails to fill a control due to an error,
no errors are returned and v4l2_g_ctrl() returns success on a
failed operation, which may cause applications to fail.

Add an error check at get_ctrl() and ensure that it will
be returned to userspace without filling the control value if
get_ctrl() fails.

Fixes: 71c689dc2e73 ("media: v4l2-ctrls: split up into four source files")
Cc: stable@vger.kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

+11 -6
+11 -6
drivers/media/v4l2-core/v4l2-ctrls-api.c
··· 753 753 for (i = 0; i < master->ncontrols; i++) 754 754 cur_to_new(master->cluster[i]); 755 755 ret = call_op(master, g_volatile_ctrl); 756 - new_to_user(c, ctrl); 756 + if (!ret) 757 + ret = new_to_user(c, ctrl); 757 758 } else { 758 - cur_to_user(c, ctrl); 759 + ret = cur_to_user(c, ctrl); 759 760 } 760 761 v4l2_ctrl_unlock(master); 761 762 return ret; ··· 771 770 if (!ctrl || !ctrl->is_int) 772 771 return -EINVAL; 773 772 ret = get_ctrl(ctrl, &c); 774 - control->value = c.value; 773 + 774 + if (!ret) 775 + control->value = c.value; 776 + 775 777 return ret; 776 778 } 777 779 EXPORT_SYMBOL(v4l2_g_ctrl); ··· 815 811 int ret; 816 812 817 813 v4l2_ctrl_lock(ctrl); 818 - user_to_new(c, ctrl); 819 - ret = set_ctrl(fh, ctrl, 0); 814 + ret = user_to_new(c, ctrl); 820 815 if (!ret) 821 - cur_to_user(c, ctrl); 816 + ret = set_ctrl(fh, ctrl, 0); 817 + if (!ret) 818 + ret = cur_to_user(c, ctrl); 822 819 v4l2_ctrl_unlock(ctrl); 823 820 return ret; 824 821 }