6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil hverkuil+cisco@kernel.org
commit 4bd8a6147645480d550242ff816b4c7ba160e5b7 upstream.
The vivid driver supports the <Vendor Command With ID> message, but if the Vendor ID of the received message didn't match the Vendor ID of the CEC Adapter, then it ignores it (good) and returns 0 (bad).
It should return -ENOMSG to indicate that other followers should be asked to handle it. Return code 0 means that the driver handled it, which is wrong in this case.
As a result, userspace followers never get the chance to process such a message.
Refactor the code a bit to have the function return -ENOMSG at the end, drop the default case, and ensure that the message handlers return 0.
That way 0 is only returned if the message is actually handled in the vivid_received() function.
Fixes: 812765cd6954 ("media: vivid: add <Vendor Command With ID> support") Cc: stable@vger.kernel.org Signed-off-by: Hans Verkuil hverkuil+cisco@kernel.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/test-drivers/vivid/vivid-cec.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/media/test-drivers/vivid/vivid-cec.c b/drivers/media/test-drivers/vivid/vivid-cec.c index 356a988dd6a1..2d15fdd5d999 100644 --- a/drivers/media/test-drivers/vivid/vivid-cec.c +++ b/drivers/media/test-drivers/vivid/vivid-cec.c @@ -327,7 +327,7 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) char osd[14];
if (!cec_is_sink(adap)) - return -ENOMSG; + break; cec_ops_set_osd_string(msg, &disp_ctl, osd); switch (disp_ctl) { case CEC_OP_DISP_CTL_DEFAULT: @@ -348,7 +348,7 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) cec_transmit_msg(adap, &reply, false); break; } - break; + return 0; } case CEC_MSG_VENDOR_COMMAND_WITH_ID: { u32 vendor_id; @@ -379,7 +379,7 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) if (size == 1) { // Ignore even op values if (!(vendor_cmd[0] & 1)) - break; + return 0; reply.len = msg->len; memcpy(reply.msg + 1, msg->msg + 1, msg->len - 1); reply.msg[msg->len - 1]++; @@ -388,12 +388,10 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) CEC_OP_ABORT_INVALID_OP); } cec_transmit_msg(adap, &reply, false); - break; + return 0; } - default: - return -ENOMSG; } - return 0; + return -ENOMSG; }
static const struct cec_adap_ops vivid_cec_adap_ops = {