From patchwork Mon Jan 7 13:04:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 10750559 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EFF7A6C5 for ; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF71D2858D for ; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D3B71289F1; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 64D2D2858D for ; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731254AbfAGNEr (ORCPT ); Mon, 7 Jan 2019 08:04:47 -0500 Received: from lb3-smtp-cloud7.xs4all.net ([194.109.24.31]:40807 "EHLO lb3-smtp-cloud7.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731273AbfAGNEo (ORCPT ); Mon, 7 Jan 2019 08:04:44 -0500 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud7.xs4all.net with ESMTPA id gUa5gGVcvBDyIgUa9gNvGy; Mon, 07 Jan 2019 14:04:41 +0100 From: hverkuil-cisco@xs4all.nl To: linux-media@vger.kernel.org Cc: Sakari Ailus , Hans Verkuil Subject: [PATCHv2 1/3] vb2: add buf_out_validate callback Date: Mon, 7 Jan 2019 14:04:35 +0100 Message-Id: <20190107130437.23732-2-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190107130437.23732-1-hverkuil-cisco@xs4all.nl> References: <20190107130437.23732-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfDCmRx3XpwoRyhsCu+I6BOjpwOPbiD9WkNw+/WsSfupulCB+iENqYf43Ic7HhaXqJoItpo/ckeEkyBGiyKgpQtT3FPCMlCXFCJ3dPj9DKtgT/skZw9TP Acxfif5kN3yNE5SAgVp1m8vugqREVyr9pSnb2QogCTY1cBGNcm25x31+vEegDYIrZxYMkSLIEInYpsZPiajlK5vWMGl+9PpD8/n1lJOlLgdteCSttU+7G4i2 FtlYoMRRCaF5LO8f3zy4/F5FvkUp1vx6+7zS/DSzs3c= Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Verkuil Adding the request API uncovered a pre-existing problem with validating output buffers. The problem is that for output buffers the driver has to validate the 'field' field of struct v4l2_buffer. This is critical when encoding or deinterlacing interlaced video. Drivers always did this in the buf_prepare callback, but that is not called from VIDIOC_QBUF in two situations: when queueing a buffer to a request and if VIDIOC_PREPARE_BUF has been called earlier for that buffer. As a result of this the 'field' value is not validated. While the first case (queueing a buffer to a request) is request API specific, the second case (VIDIOC_PREPARE_BUF has been called earlier for that buffer) was always wrong. This patch adds a new buf_out_validate callback to validate the output buffer at QBUF time. Note that PREPARE_BUF doesn't need to validate this: it just locks the buffer memory and doesn't need nor want to know about how this buffer is actually going to be used. It's the QBUF ioctl that determines this. This issue was found by v4l2-compliance since it failed to replace V4L2_FIELD_ANY by a proper field value when testing the vivid video output in combination with requests. There never was a test before for the PREPARE_BUF/QBUF case, so even though this bug has been present for quite some time, it was never noticed. Signed-off-by: Hans Verkuil --- drivers/media/common/videobuf2/videobuf2-core.c | 14 +++++++++++--- include/media/videobuf2-core.h | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 70e8c3366f9c..653e933db854 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -499,9 +499,9 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) pr_info(" buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n", vb->cnt_buf_init, vb->cnt_buf_cleanup, vb->cnt_buf_prepare, vb->cnt_buf_finish); - pr_info(" buf_queue: %u buf_done: %u buf_request_complete: %u\n", - vb->cnt_buf_queue, vb->cnt_buf_done, - vb->cnt_buf_request_complete); + pr_info(" buf_out_validate: %u buf_queue: %u buf_done: %u buf_request_complete: %u\n", + vb->cnt_buf_out_validate, vb->cnt_buf_queue, + vb->cnt_buf_done, vb->cnt_buf_request_complete); pr_info(" alloc: %u put: %u prepare: %u finish: %u mmap: %u\n", vb->cnt_mem_alloc, vb->cnt_mem_put, vb->cnt_mem_prepare, vb->cnt_mem_finish, @@ -1510,6 +1510,14 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, return -EBUSY; } + if (q->is_output) { + ret = call_vb_qop(vb, buf_out_validate, vb); + if (ret) { + dprintk(1, "buffer validation failed\n"); + return ret; + } + } + if (req) { int ret; diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 4a737b2c610b..91f1e66aacc6 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -296,6 +296,7 @@ struct vb2_buffer { u32 cnt_mem_num_users; u32 cnt_mem_mmap; + u32 cnt_buf_out_validate; u32 cnt_buf_init; u32 cnt_buf_prepare; u32 cnt_buf_finish; @@ -342,6 +343,9 @@ struct vb2_buffer { * @wait_finish: reacquire all locks released in the previous callback; * required to continue operation after sleeping while * waiting for a new buffer to arrive. + * @buf_out_validate: called every time the output buffer is queued from + * userspace; drivers can use this to validate + * userspace-provided information; optional. * @buf_init: called once after allocating a buffer (in MMAP case) * or after acquiring a new USERPTR buffer; drivers may * perform additional buffer-related initialization; @@ -409,6 +413,7 @@ struct vb2_ops { void (*wait_prepare)(struct vb2_queue *q); void (*wait_finish)(struct vb2_queue *q); + int (*buf_out_validate)(struct vb2_buffer *vb); int (*buf_init)(struct vb2_buffer *vb); int (*buf_prepare)(struct vb2_buffer *vb); void (*buf_finish)(struct vb2_buffer *vb); From patchwork Mon Jan 7 13:04:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 10750557 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 338F717D2 for ; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F0B62858D for ; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 12CF5289F2; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFABC28732 for ; Mon, 7 Jan 2019 13:04:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730835AbfAGNEs (ORCPT ); Mon, 7 Jan 2019 08:04:48 -0500 Received: from lb3-smtp-cloud7.xs4all.net ([194.109.24.31]:35661 "EHLO lb3-smtp-cloud7.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731274AbfAGNEn (ORCPT ); Mon, 7 Jan 2019 08:04:43 -0500 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud7.xs4all.net with ESMTPA id gUa5gGVcvBDyIgUa9gNvH5; Mon, 07 Jan 2019 14:04:42 +0100 From: hverkuil-cisco@xs4all.nl To: linux-media@vger.kernel.org Cc: Sakari Ailus , Hans Verkuil Subject: [PATCHv2 2/3] vim2m: add buf_out_validate callback Date: Mon, 7 Jan 2019 14:04:36 +0100 Message-Id: <20190107130437.23732-3-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190107130437.23732-1-hverkuil-cisco@xs4all.nl> References: <20190107130437.23732-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfMl+v30e46w9XJsUfwZQhdbdXI0rgfk1pP/u3gtl50KHGTrrbsiT38FD5FxBm7ARRLMTX64fyq2EbL19csasj3G9mUYELdj2EI9r/wepQPw11TDvUuXh 1gZkKlFxErab4LtJT9Qt64pfnXPD0Qm9VwjoyoYDD4cDrBxo1I7tBiW+GTS4JBuSujdCKIu99VraLZnHeG9nvCmAWBhmM92uCjAeNSkg4D7ZeI0zwonwRLbG D7FfS1C9tWo2SKvvgyo0kge60s1sl/h4FEcUo694CQY= Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Verkuil Split off the field validation from buf_prepare into a new buf_out_validate function. Field validation for output buffers should be done there since buf_prepare is not guaranteed to be called at QBUF time. Signed-off-by: Hans Verkuil --- drivers/media/platform/vim2m.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index d01821a6906a..4a16b7a6b69a 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -753,15 +753,13 @@ static int vim2m_queue_setup(struct vb2_queue *vq, return 0; } -static int vim2m_buf_prepare(struct vb2_buffer *vb) +static int vim2m_buf_out_validate(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct vim2m_q_data *q_data; dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); - q_data = get_q_data(ctx, vb->vb2_queue->type); if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { if (vbuf->field == V4L2_FIELD_ANY) vbuf->field = V4L2_FIELD_NONE; @@ -772,6 +770,17 @@ static int vim2m_buf_prepare(struct vb2_buffer *vb) } } + return 0; +} + +static int vim2m_buf_prepare(struct vb2_buffer *vb) +{ + struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct vim2m_q_data *q_data; + + dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); + + q_data = get_q_data(ctx, vb->vb2_queue->type); if (vb2_plane_size(vb, 0) < q_data->sizeimage) { dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n", __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage); @@ -832,6 +841,7 @@ static void vim2m_buf_request_complete(struct vb2_buffer *vb) static const struct vb2_ops vim2m_qops = { .queue_setup = vim2m_queue_setup, + .buf_out_validate = vim2m_buf_out_validate, .buf_prepare = vim2m_buf_prepare, .buf_queue = vim2m_buf_queue, .start_streaming = vim2m_start_streaming, From patchwork Mon Jan 7 13:04:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 10750555 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 10B9D14DE for ; Mon, 7 Jan 2019 13:04:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3DBC289F1 for ; Mon, 7 Jan 2019 13:04:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E7877289F2; Mon, 7 Jan 2019 13:04:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F5052858D for ; Mon, 7 Jan 2019 13:04:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731275AbfAGNEs (ORCPT ); Mon, 7 Jan 2019 08:04:48 -0500 Received: from lb2-smtp-cloud7.xs4all.net ([194.109.24.28]:46399 "EHLO lb2-smtp-cloud7.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730833AbfAGNEn (ORCPT ); Mon, 7 Jan 2019 08:04:43 -0500 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud7.xs4all.net with ESMTPA id gUa5gGVcvBDyIgUaAgNvHC; Mon, 07 Jan 2019 14:04:42 +0100 From: hverkuil-cisco@xs4all.nl To: linux-media@vger.kernel.org Cc: Sakari Ailus , Hans Verkuil Subject: [PATCHv2 3/3] vivid: add buf_out_validate callback Date: Mon, 7 Jan 2019 14:04:37 +0100 Message-Id: <20190107130437.23732-4-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190107130437.23732-1-hverkuil-cisco@xs4all.nl> References: <20190107130437.23732-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfMl+v30e46w9XJsUfwZQhdbdXI0rgfk1pP/u3gtl50KHGTrrbsiT38FD5FxBm7ARRLMTX64fyq2EbL19csasj3G9mUYELdj2EI9r/wepQPw11TDvUuXh 1gZkKlFxErab4LtJT9Qt64pfnXPD0Qm9VwjoyoYDD4cDrBxo1I7tBiW+GTS4JBuSujdCKIu99VraLZnHeG9nvCmAWBhmM92uCjAeNSkg4D7ZeI0zwonwRLbG D7FfS1C9tWo2SKvvgyo0kge60s1sl/h4FEcUo694CQY= Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Verkuil Split off the field validation from buf_prepare into a new buf_out_validate function. Field validation for output buffers should be done there since buf_prepare is not guaranteed to be called at QBUF time. Signed-off-by: Hans Verkuil --- drivers/media/platform/vivid/vivid-vid-out.c | 23 ++++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index ea250aee2b2e..e45753a1adde 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -81,10 +81,24 @@ static int vid_out_queue_setup(struct vb2_queue *vq, return 0; } -static int vid_out_buf_prepare(struct vb2_buffer *vb) +static int vid_out_buf_out_validate(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + + dprintk(dev, 1, "%s\n", __func__); + + if (dev->field_out != V4L2_FIELD_ALTERNATE) + vbuf->field = dev->field_out; + else if (vbuf->field != V4L2_FIELD_TOP && + vbuf->field != V4L2_FIELD_BOTTOM) + return -EINVAL; + return 0; +} + +static int vid_out_buf_prepare(struct vb2_buffer *vb) +{ + struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); unsigned long size; unsigned planes; unsigned p; @@ -105,12 +119,6 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb) return -EINVAL; } - if (dev->field_out != V4L2_FIELD_ALTERNATE) - vbuf->field = dev->field_out; - else if (vbuf->field != V4L2_FIELD_TOP && - vbuf->field != V4L2_FIELD_BOTTOM) - return -EINVAL; - for (p = 0; p < planes; p++) { size = dev->bytesperline_out[p] * dev->fmt_out_rect.height + vb->planes[p].data_offset; @@ -188,6 +196,7 @@ static void vid_out_buf_request_complete(struct vb2_buffer *vb) const struct vb2_ops vivid_vid_out_qops = { .queue_setup = vid_out_queue_setup, + .buf_out_validate = vid_out_buf_out_validate, .buf_prepare = vid_out_buf_prepare, .buf_queue = vid_out_buf_queue, .start_streaming = vid_out_start_streaming,