From patchwork Tue Oct 22 09:38:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 3081641 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9B7E49F372 for ; Tue, 22 Oct 2013 09:38:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EE60920494 for ; Tue, 22 Oct 2013 09:38:34 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 8A9CE2048F for ; Tue, 22 Oct 2013 09:38:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6E8B0E6A9A for ; Tue, 22 Oct 2013 02:38:33 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay.fireflyinternet.com (server109-228-28-164.live-servers.net [109.228.28.164]) by gabe.freedesktop.org (Postfix) with ESMTP id 5A841E61BD for ; Tue, 22 Oct 2013 02:38:19 -0700 (PDT) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.73.22; Received: from haswell.alporthouse.com (unverified [78.156.73.22]) by relay.fireflyinternet.com (FireflyRelay1) with ESMTP id 9830500-2000100 for multiple; Tue, 22 Oct 2013 10:39:23 +0100 From: Chris Wilson To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm: Restrict ioctl size to kernel struct size Date: Tue, 22 Oct 2013 10:38:03 +0100 Message-Id: <1382434683-32048-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.8.4.rc3 In-Reply-To: <20131017001235.3077.92963.stgit@IRBT4585> References: <20131017001235.3077.92963.stgit@IRBT4585> X-Authenticated-User: chris.alporthouse@surfanytime.net Cc: Pavel Roskin X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Prevent the user from passing in an ioctl command with up to 16,383 bytes specified for the struct to be allocated and copied, and instead only allocate enough space to satisfy the kernel. Suggested-by: Pavel Roskin Signed-off-by: Chris Wilson Cc: Pavel Roskin Cc: dri-devel@lists.freedesktop.org Reviewed-by: Ville Syrjälä Reviewed-by: Pavel Roskin --- drivers/gpu/drm/drm_drv.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 05ad9ba0a67e..8c5fbc9d41ad 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -354,6 +354,16 @@ static int drm_version(struct drm_device *dev, void *data, return err; } +static unsigned ioctl_size(unsigned kcmd, unsigned ucmd, unsigned *ksize, unsigned *usize) +{ + *ksize = _IOC_SIZE(kcmd); + *usize = _IOC_SIZE(ucmd); + if (*usize > *ksize) + *usize = *ksize; + + return kcmd; +} + /** * Called whenever a process performs an ioctl on /dev/drm. * @@ -393,25 +403,11 @@ long drm_ioctl(struct file *filp, goto err_i1; if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { - u32 drv_size; ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; - drv_size = _IOC_SIZE(ioctl->cmd_drv); - usize = asize = _IOC_SIZE(cmd); - if (drv_size > asize) - asize = drv_size; - cmd = ioctl->cmd_drv; - } - else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { - u32 drv_size; - + cmd = ioctl_size(ioctl->cmd_drv, cmd, &asize, &usize); + } else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { ioctl = &drm_ioctls[nr]; - - drv_size = _IOC_SIZE(ioctl->cmd); - usize = asize = _IOC_SIZE(cmd); - if (drv_size > asize) - asize = drv_size; - - cmd = ioctl->cmd; + cmd = ioctl_size(ioctl->cmd, cmd, &asize, &usize); } else goto err_i1;