From patchwork Tue Nov 26 16:18:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 180219 Delivered-To: patch@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp4850909ilf; Tue, 26 Nov 2019 08:18:59 -0800 (PST) X-Google-Smtp-Source: APXvYqy2TY8vZQDN+wBagWuCY7Vddl7+DL5r8pl9WQlUi/Xp3d5yYbTss9+QjNkHeRBWQLHVxQbR X-Received: by 2002:a5d:528e:: with SMTP id c14mr2861275wrv.308.1574785139669; Tue, 26 Nov 2019 08:18:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574785139; cv=none; d=google.com; s=arc-20160816; b=L6m8TqkmwWgmc6bmXVwtxWazmP9Dp4p4hVz72hrcQMlPfvzgJ8n2ONbHY7uhoQcqIF kkDDhWgKLj1pb2OBVZmxDWBeFJFWCvyBO9YbArOawBv/zrgeTw/79RK0cO2OgsMZINUc cqI8G/ebg5VtQxMId9+LEe6vDB7amV2SRFdieHImQ1StXDrCFkIlE6KOV33rtFCll+4P QFIBHApSL52EarEb6QTihwBUCs9g46QilIos9q57sajwcgBjXxxNzRUij4rYcFy6Da+l 5RTgdBZZDMkpJaDFCR/OzLFg3Q6SSjGigrmiX1nrJs9d4dG4rkWE/vaVH2fnFnKutPOl 8myw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=fePHKKsfOVuGXsKVpbjFMGrnfLohKJaEZUEnVUmAmVY=; b=Tl4donMoIz2/xc1/sNAKnOmXpjylgF3NmCX8YFmownrk69R22Q4BMdCyAuUjffWvre 5D/i7oIFY0O4YJ6qEA+YldhRpLYzWMH39JYxLUgN7hDKQd9HMtMwfFTdUAlNr6j0KHMc TQC7KlCBwg+zEhaVKEdaflga9BxUmr+iXzCFSKKmE9io9sy9f9GIAm3YWZg+fixZmN7J Nyz3zV7ZFJz7K8KLBFRJlsxZiiQIKTsL64VsD4R/MEY+1oxWQlxXqToMrkMckw72Gg92 jlPNAiRwabb6QOmizqFPhLiJBxRi4du9TEXYtVldvMoCDUSP0R5GGXPcxmlZGrN91/4+ dk0w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v2si9710114ede.61.2019.11.26.08.18.59; Tue, 26 Nov 2019 08:18:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728795AbfKZQS6 (ORCPT + 4 others); Tue, 26 Nov 2019 11:18:58 -0500 Received: from mout.kundenserver.de ([212.227.17.13]:36079 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728482AbfKZQSl (ORCPT ); Tue, 26 Nov 2019 11:18:41 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue106 [212.227.15.145]) with ESMTPA (Nemesis) id 1MXpM2-1iJ6CU1iea-00Y739; Tue, 26 Nov 2019 17:18:34 +0100 From: Arnd Bergmann To: linux-media@vger.kernel.org, Hans Verkuil , Mauro Carvalho Chehab Cc: y2038@lists.linaro.org, linux-kernel@vger.kernel.org, Arnd Bergmann , stable@vger.kernel.org Subject: [PATCH v5 3/8] media: v4l2-core: compat: ignore native command codes Date: Tue, 26 Nov 2019 17:18:19 +0100 Message-Id: <20191126161824.337724-4-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20191126161824.337724-1-arnd@arndb.de> References: <20191126161824.337724-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:8TVU09gCY/FDOx2lpPLRMrqStt5USuA8OZ/VNhJVsJd7Gp2m6VG /CCIxU67Re6TN6SAYn+YT/I9ENEI+kNFH8azFfNX8g3VlCFAaio0bk4ceLXZotffLjceA8o +0UAIkt8AM4ad6h0wa+aWlWuF3T3z2Oze0/WR8mnh3McT2/BvwRVuAwru8AgKlqh2OEYs5/ UiH7sZBj+mycLuCRblppQ== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:3g7yQIiD7f0=:w9zH2Q7cCkdJYLv/T7HEIv Coqr90Cou4tLIM8r88ERA15pv2UlJpp8o4tVGTc3r8ttTGUHTd3Xi2/DHi0c4Uq3rDMjIjacF ULP/r3VTJMYTCNXF94MniIvaQpcTTUvarr2ktYhxqsgFYmhDUzh9YSAgm1UR4p6Ep9ms6jdFU 9TrWcAdGYR2LuCflaLeXr5sRuz6K4p6cqqbKBSL+7ywcZjgpDWeazCE4hGEn7G25OLcbFEBy0 5eoJJPXPzK9NKgM9otoAf0tAqE1XWdM7iDR7nJ3nP1pCIRsoo0+RVshyoLYrjPyYBiAyJfR1H WzKT/pYjVGaZBL/Vfe3JDLicZEjbUE+IL4vQsdwrXpw1yms3YB360P1jO4BMKHt0A/mckKW4t 9RWhvjRxpUYZxKXaOwe993II2bW17ITAQl8RNeDv2oHsXpSULHbhLN4SolADAnrEuGM5UdVxA Dkej/SrNWJJoC0B09dOD3GnbI7FJ09ipow2SwaYtFCgkbEvjR17kxl0XCt4YQQEufZ2iSdDOZ YayhC+g3Mr6X/lYT/k1K39Xdi3RDvoxmzTnj7GJAiV3HOAuSD3mStvgEUoyYSrgRYA6sTBAqp XadhDDLQudcCCrLS5kwyZ7XW2z6qG0D3dwD3Aw3mUX6vxHuJ5S0hsI1iFE4XxskVB0+1gZ16f oxosnRe53BOH0xUHF4SNB3ghjK/23OKWdd6xhjsQIk/feDHcY4xLqxLSam8XNtzrclXZlAskX 3gUbrT2nLAS79D4IWJq36RBzHVauAsg/JuAIMfQjE0UroVCobGWPy3JXeZXpdStSIDOZgCTnc 1m0OvClYAo4quobSsLstKuO9GAkX5/DoAEtDnnC03du8d1gYUXllSYfVTGqaGUHDYijNpRd9t MCqtTKXbThlg0+PpuXyQ== Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The do_video_ioctl() compat handler converts the compat command codes into the native ones before processing further, but this causes problems for 32-bit user applications that pass a command code that matches a 64-bit native number, which will then be handled the same way. Specifically, this breaks VIDIOC_DQEVENT_TIME from user space applications with 64-bit time_t, as the structure layout is the same as the native 64-bit layout on many architectures (x86 being the notable exception). Change the handler to use the converted command code only for passing into the native ioctl handler, not for deciding on the conversion, in order to make the compat behavior match the native behavior. Actual support for the 64-bit time_t version of VIDIOC_DQEVENT_TIME and other commands still needs to be added in a separate patch. Cc: stable@vger.kernel.org Signed-off-by: Arnd Bergmann --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 148 +++++++++--------- 1 file changed, 75 insertions(+), 73 deletions(-) -- 2.20.0 diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index e1eaf1135c7f..7ad6db8dd9f6 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -1183,36 +1183,38 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar u32 aux_space; int compatible_arg = 1; long err = 0; + unsigned int ncmd; /* * 1. When struct size is different, converts the command. */ switch (cmd) { - case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; - case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; - case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; - case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break; - case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break; - case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break; - case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break; - case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break; - case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break; - case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; - case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break; - case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break; - case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break; - case VIDIOC_DQEVENT32: cmd = VIDIOC_DQEVENT; break; - case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; - case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; - case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; - case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; - case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; - case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; - case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; - case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break; - case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break; - case VIDIOC_G_EDID32: cmd = VIDIOC_G_EDID; break; - case VIDIOC_S_EDID32: cmd = VIDIOC_S_EDID; break; + case VIDIOC_G_FMT32: ncmd = VIDIOC_G_FMT; break; + case VIDIOC_S_FMT32: ncmd = VIDIOC_S_FMT; break; + case VIDIOC_QUERYBUF32: ncmd = VIDIOC_QUERYBUF; break; + case VIDIOC_G_FBUF32: ncmd = VIDIOC_G_FBUF; break; + case VIDIOC_S_FBUF32: ncmd = VIDIOC_S_FBUF; break; + case VIDIOC_QBUF32: ncmd = VIDIOC_QBUF; break; + case VIDIOC_DQBUF32: ncmd = VIDIOC_DQBUF; break; + case VIDIOC_ENUMSTD32: ncmd = VIDIOC_ENUMSTD; break; + case VIDIOC_ENUMINPUT32: ncmd = VIDIOC_ENUMINPUT; break; + case VIDIOC_TRY_FMT32: ncmd = VIDIOC_TRY_FMT; break; + case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break; + case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break; + case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break; + case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break; + case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break; + case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break; + case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break; + case VIDIOC_G_INPUT32: ncmd = VIDIOC_G_INPUT; break; + case VIDIOC_S_INPUT32: ncmd = VIDIOC_S_INPUT; break; + case VIDIOC_G_OUTPUT32: ncmd = VIDIOC_G_OUTPUT; break; + case VIDIOC_S_OUTPUT32: ncmd = VIDIOC_S_OUTPUT; break; + case VIDIOC_CREATE_BUFS32: ncmd = VIDIOC_CREATE_BUFS; break; + case VIDIOC_PREPARE_BUF32: ncmd = VIDIOC_PREPARE_BUF; break; + case VIDIOC_G_EDID32: ncmd = VIDIOC_G_EDID; break; + case VIDIOC_S_EDID32: ncmd = VIDIOC_S_EDID; break; + default: ncmd = cmd; break; } /* @@ -1221,11 +1223,11 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar * argument into it. */ switch (cmd) { - case VIDIOC_OVERLAY: - case VIDIOC_STREAMON: - case VIDIOC_STREAMOFF: - case VIDIOC_S_INPUT: - case VIDIOC_S_OUTPUT: + case VIDIOC_OVERLAY32: + case VIDIOC_STREAMON32: + case VIDIOC_STREAMOFF32: + case VIDIOC_S_INPUT32: + case VIDIOC_S_OUTPUT32: err = alloc_userspace(sizeof(unsigned int), 0, &new_p64); if (!err && assign_in_user((unsigned int __user *)new_p64, (compat_uint_t __user *)p32)) @@ -1233,23 +1235,23 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar compatible_arg = 0; break; - case VIDIOC_G_INPUT: - case VIDIOC_G_OUTPUT: + case VIDIOC_G_INPUT32: + case VIDIOC_G_OUTPUT32: err = alloc_userspace(sizeof(unsigned int), 0, &new_p64); compatible_arg = 0; break; - case VIDIOC_G_EDID: - case VIDIOC_S_EDID: + case VIDIOC_G_EDID32: + case VIDIOC_S_EDID32: err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64); if (!err) err = get_v4l2_edid32(new_p64, p32); compatible_arg = 0; break; - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: + case VIDIOC_G_FMT32: + case VIDIOC_S_FMT32: + case VIDIOC_TRY_FMT32: err = bufsize_v4l2_format(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_format), @@ -1262,7 +1264,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar compatible_arg = 0; break; - case VIDIOC_CREATE_BUFS: + case VIDIOC_CREATE_BUFS32: err = bufsize_v4l2_create(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_create_buffers), @@ -1275,10 +1277,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar compatible_arg = 0; break; - case VIDIOC_PREPARE_BUF: - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: + case VIDIOC_PREPARE_BUF32: + case VIDIOC_QUERYBUF32: + case VIDIOC_QBUF32: + case VIDIOC_DQBUF32: err = bufsize_v4l2_buffer(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_buffer), @@ -1291,7 +1293,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar compatible_arg = 0; break; - case VIDIOC_S_FBUF: + case VIDIOC_S_FBUF32: err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0, &new_p64); if (!err) @@ -1299,13 +1301,13 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar compatible_arg = 0; break; - case VIDIOC_G_FBUF: + case VIDIOC_G_FBUF32: err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0, &new_p64); compatible_arg = 0; break; - case VIDIOC_ENUMSTD: + case VIDIOC_ENUMSTD32: err = alloc_userspace(sizeof(struct v4l2_standard), 0, &new_p64); if (!err) @@ -1313,16 +1315,16 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar compatible_arg = 0; break; - case VIDIOC_ENUMINPUT: + case VIDIOC_ENUMINPUT32: err = alloc_userspace(sizeof(struct v4l2_input), 0, &new_p64); if (!err) err = get_v4l2_input32(new_p64, p32); compatible_arg = 0; break; - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: + case VIDIOC_G_EXT_CTRLS32: + case VIDIOC_S_EXT_CTRLS32: + case VIDIOC_TRY_EXT_CTRLS32: err = bufsize_v4l2_ext_controls(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_ext_controls), @@ -1334,7 +1336,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar } compatible_arg = 0; break; - case VIDIOC_DQEVENT: + case VIDIOC_DQEVENT32: err = alloc_userspace(sizeof(struct v4l2_event), 0, &new_p64); compatible_arg = 0; break; @@ -1352,9 +1354,9 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar * Otherwise, it will pass the newly allocated @new_p64 argument. */ if (compatible_arg) - err = native_ioctl(file, cmd, (unsigned long)p32); + err = native_ioctl(file, ncmd, (unsigned long)p32); else - err = native_ioctl(file, cmd, (unsigned long)new_p64); + err = native_ioctl(file, ncmd, (unsigned long)new_p64); if (err == -ENOTTY) return err; @@ -1370,13 +1372,13 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar * the blocks to maximum allowed value. */ switch (cmd) { - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: + case VIDIOC_G_EXT_CTRLS32: + case VIDIOC_S_EXT_CTRLS32: + case VIDIOC_TRY_EXT_CTRLS32: if (put_v4l2_ext_controls32(file, new_p64, p32)) err = -EFAULT; break; - case VIDIOC_S_EDID: + case VIDIOC_S_EDID32: if (put_v4l2_edid32(new_p64, p32)) err = -EFAULT; break; @@ -1389,49 +1391,49 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar * the original 32 bits structure. */ switch (cmd) { - case VIDIOC_S_INPUT: - case VIDIOC_S_OUTPUT: - case VIDIOC_G_INPUT: - case VIDIOC_G_OUTPUT: + case VIDIOC_S_INPUT32: + case VIDIOC_S_OUTPUT32: + case VIDIOC_G_INPUT32: + case VIDIOC_G_OUTPUT32: if (assign_in_user((compat_uint_t __user *)p32, ((unsigned int __user *)new_p64))) err = -EFAULT; break; - case VIDIOC_G_FBUF: + case VIDIOC_G_FBUF32: err = put_v4l2_framebuffer32(new_p64, p32); break; - case VIDIOC_DQEVENT: + case VIDIOC_DQEVENT32: err = put_v4l2_event32(new_p64, p32); break; - case VIDIOC_G_EDID: + case VIDIOC_G_EDID32: err = put_v4l2_edid32(new_p64, p32); break; - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: + case VIDIOC_G_FMT32: + case VIDIOC_S_FMT32: + case VIDIOC_TRY_FMT32: err = put_v4l2_format32(new_p64, p32); break; - case VIDIOC_CREATE_BUFS: + case VIDIOC_CREATE_BUFS32: err = put_v4l2_create32(new_p64, p32); break; - case VIDIOC_PREPARE_BUF: - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: + case VIDIOC_PREPARE_BUF32: + case VIDIOC_QUERYBUF32: + case VIDIOC_QBUF32: + case VIDIOC_DQBUF32: err = put_v4l2_buffer32(new_p64, p32); break; - case VIDIOC_ENUMSTD: + case VIDIOC_ENUMSTD32: err = put_v4l2_standard32(new_p64, p32); break; - case VIDIOC_ENUMINPUT: + case VIDIOC_ENUMINPUT32: err = put_v4l2_input32(new_p64, p32); break; } From patchwork Tue Nov 26 16:18:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 180215 Delivered-To: patch@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp4850497ilf; Tue, 26 Nov 2019 08:18:45 -0800 (PST) X-Google-Smtp-Source: APXvYqw2bO3nObmGUmFk4O/lGP0DG6PEpZJB1t0Y2N76Sp2QYpoSROjkpxvN8yWEhEm8DqNdue6z X-Received: by 2002:aa7:d98b:: with SMTP id u11mr26603136eds.152.1574785124900; Tue, 26 Nov 2019 08:18:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574785124; cv=none; d=google.com; s=arc-20160816; b=plhNF6M6R7hR7xreEH/eSrQC6QNiJkDxB/trH22VJqDLwiNXvMmPLNo9znrz0WJIgY MuHLW2GzQdVYp0ARgLuHScrqZe2UAimH5JbXqH+LiokI4+VUGioYTsxMbdqfa0eF3I02 G7Y5MM+Hpx3hO8a1YUiF35z1mu9xKLCUhtjVxwWezuqJ3cc9de3pk9FakONuFjvmVcND 6iR+DobRSa9qvv84OvrgX7NlaajMhMz2j1w+eZFfTtZMmLPF9dlKg+toLVtWLKpTBgzL C3EyP2bwCUmRdgqEOU4F5Ja8LkQplBAkB5YoSDUn0k87lbQX6uC1AbnyV0KH27wdgVOJ WNqQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=bheb3Pl3koFxVFS1mqzlOn3dp9DrrwaIOVbuSISOTq4=; b=K87MbIxmayaYYY0rQULNkOMunvcKM1+0zxg9aekqSxiu/K+3hi8NkS8VZti3emA05+ eekFlMbB7BteGTRCZ1LAnedqOVrlBnNudDIH6Fd/4EzcmxQCst1yEJKlfYyUqUSAfwHe 8Fat/CxFoWvejcwf1RAG7byiktua01pB8GN/BK4yz5W0i+sRfxV0vsiOtYzsQPbZM3Tz i1fiQ28dr9M6B+HZEQyL75YLo3K2aI3ra2ollqUhFrk1sIMZ1QaEW1iy85T5s3f4+I7s Ba3v8Ziv6ym/GgjYTC3VcZcrr3Wvb5HWwHB2vAoHMp1jeJpdpl+7ShlNJgGMJjwRx4Q1 2XJA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i30si8857070edd.124.2019.11.26.08.18.44; Tue, 26 Nov 2019 08:18:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728753AbfKZQSo (ORCPT + 4 others); Tue, 26 Nov 2019 11:18:44 -0500 Received: from mout.kundenserver.de ([217.72.192.73]:41867 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728739AbfKZQSn (ORCPT ); Tue, 26 Nov 2019 11:18:43 -0500 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue106 [212.227.15.145]) with ESMTPA (Nemesis) id 1MVMNF-1iPzA41o6p-00SLUS; Tue, 26 Nov 2019 17:18:35 +0100 From: Arnd Bergmann To: linux-media@vger.kernel.org, Hans Verkuil , Mauro Carvalho Chehab Cc: y2038@lists.linaro.org, linux-kernel@vger.kernel.org, Arnd Bergmann Subject: [PATCH v5 7/8] media: v4l2-core: fix compat VIDIOC_DQEVENT for time64 ABI Date: Tue, 26 Nov 2019 17:18:23 +0100 Message-Id: <20191126161824.337724-8-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20191126161824.337724-1-arnd@arndb.de> References: <20191126161824.337724-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:qkDInfKyka/nqbgHNepwaYQ0KDWIvFoJWlOVAt4iyAlq2n+FRmC 3goPaARuNQpQYprSzLsXcU78Bqo3gcxjS4Iq7goI8U5UI1tMUPjmdX1clWUVcXL753XbkSY csi3EZbLwzIvX3Ewnqkc5gqN2swEPngz/8xUlCafiGm1ELmS8OAmdNf+c5sgMWD15jhTgpe QkOdDft5VnhyLoTLb/a6Q== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:NYj2HxuPskE=:pM5Nhr0wV29QHPqIlb/6Qt ebRbzJcqUzPK+7sbk9wMJAIonh0Xyqx0fW6bWSLRGEAzyPlXZ7BY8hGLw7RiyIqpj2myltoof Y4sLxgnhmPGYD/q/y2O3mwji/922PegvbPJ6aUfREV3ZOy0ztFYVElf04C5QfgybUgm8ih0+I 3TkgegXuPVw2w5L1mtxN2MkouRsCb1WJffLqigzQvlW4GMWc+9Bj4ha3jy9/beh8xqZj//Lk/ bmlURffFuuSU7f9Hw0xExtQu4UNPhi3/uLWhvsd5pbWr0M/4snMQkI6V+do7iBz53Z5R0GyCD RCQM5AZc0F7yR6OTxkYznYaXSfl+ClpN8JU2zqPVqStjBDMAr5JIFRXFk+o5DAtRYIsN7GuWX +msswJSw0I8w7VmdDsSGS8KLbHkiWufvLfRXN50vIYC9t0EkJ9v7o3CNUx3Cd3QCocfEtq2d7 9/Hbus6WgqhMCtc9le5ggdLjX8su1YMgKKU1nNaapD9DckmZJqzKuJqdielk9dW/vDGlWcm9q IPVthK+1LYE1O5kJMt03zFah8Wyo/Hi9dGyr89nXnj/6famNt8PU25hP5npj8zd+ME9rL7tEB gsyZFlmk8aNXMZvcQLM5p53ZoRvl7bmg5Ziwd5v/F09czDy23s/O0efhVYzdLb5x7/NlO/EJa 059VlnJPm5trCRIjSTddBH/EfzjlRMJya1elBvbAZAGyKcejyQxkDudj5QE4vF2mU2Q2NlEzZ nDPuob0bQdlPjCRXXcaK/AL5HTQ992z0d+4dKpjmM4TpniSkgknnCt40IlsM749UfgNwVoN8T WnEq6Ya8oR7QXXkfnCRuPGqg/CepQegXlwoa802TPXQUKB+bVytLpE4zuWaXUoaaXEYSgfGyt RiznNV+cbpyMYSXQsAkw== Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The native code supports the variant of struct v4l2_event for 64-bit time_t, so add the compat version as well. Here, a new incompatibility arises: while almost all 32-bit architectures now use the same layout as 64-bit architectures and the commands can simply be passed through, on x86 the internal alignment of v4l2_event is different because of the 64-bit member in v4l2_event_ctrl. To handle all architectures, this now requires defining four different versions of the structure to cover all possible combinations. The compat handling for VIDIOC_DQEVENT32 and VIDIOC_DQEVENT32_TIME32 is now inside of an #ifdef so it does not get used on architectures other than x86. Signed-off-by: Arnd Bergmann --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) -- 2.20.0 diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 7ad6db8dd9f6..46cd84879c1f 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -1028,6 +1028,15 @@ static int put_v4l2_ext_controls32(struct file *file, return 0; } +#ifdef CONFIG_X86_64 +/* + * x86 is the only compat architecture with different struct alignment + * between 32-bit and 64-bit tasks. + * + * On all other architectures, v4l2_event32 and v4l2_event32_time32 are + * the same as v4l2_event and v4l2_event_time32, so we can use the native + * handlers, converting v4l2_event to v4l2_event_time32 if necessary. + */ struct v4l2_event32 { __u32 type; union { @@ -1036,7 +1045,20 @@ struct v4l2_event32 { } u; __u32 pending; __u32 sequence; - struct compat_timespec timestamp; + struct __kernel_timespec timestamp; + __u32 id; + __u32 reserved[8]; +}; + +struct v4l2_event32_time32 { + __u32 type; + union { + compat_s64 value64; + __u8 data[64]; + } u; + __u32 pending; + __u32 sequence; + struct old_timespec32 timestamp; __u32 id; __u32 reserved[8]; }; @@ -1057,6 +1079,23 @@ static int put_v4l2_event32(struct v4l2_event __user *p64, return 0; } +static int put_v4l2_event32_time32(struct v4l2_event_time32 __user *p64, + struct v4l2_event32_time32 __user *p32) +{ + if (!access_ok(p32, sizeof(*p32)) || + assign_in_user(&p32->type, &p64->type) || + copy_in_user(&p32->u, &p64->u, sizeof(p64->u)) || + assign_in_user(&p32->pending, &p64->pending) || + assign_in_user(&p32->sequence, &p64->sequence) || + assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) || + assign_in_user(&p32->timestamp.tv_nsec, &p64->timestamp.tv_nsec) || + assign_in_user(&p32->id, &p64->id) || + copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved))) + return -EFAULT; + return 0; +} +#endif + struct v4l2_edid32 { __u32 pad; __u32 start_block; @@ -1121,6 +1160,7 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64, #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) #define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) #define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32) +#define VIDIOC_DQEVENT32_TIME32 _IOR ('V', 89, struct v4l2_event32_time32) #define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32) #define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32) @@ -1202,7 +1242,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break; case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break; case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break; +#ifdef CONFIG_X86_64 case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break; + case VIDIOC_DQEVENT32_TIME32: ncmd = VIDIOC_DQEVENT_TIME32; break; +#endif case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break; case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break; case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break; @@ -1336,10 +1379,16 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar } compatible_arg = 0; break; +#ifdef CONFIG_X86_64 case VIDIOC_DQEVENT32: err = alloc_userspace(sizeof(struct v4l2_event), 0, &new_p64); compatible_arg = 0; break; + case VIDIOC_DQEVENT32_TIME32: + err = alloc_userspace(sizeof(struct v4l2_event_time32), 0, &new_p64); + compatible_arg = 0; + break; +#endif } if (err) return err; @@ -1404,10 +1453,16 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar err = put_v4l2_framebuffer32(new_p64, p32); break; +#ifdef CONFIG_X86_64 case VIDIOC_DQEVENT32: err = put_v4l2_event32(new_p64, p32); break; + case VIDIOC_DQEVENT32_TIME32: + err = put_v4l2_event32_time32(new_p64, p32); + break; +#endif + case VIDIOC_G_EDID32: err = put_v4l2_edid32(new_p64, p32); break;