From patchwork Sun Dec 13 17:07:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Souza, Jose" X-Patchwork-Id: 11970895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD1C8C4361B for ; Sun, 13 Dec 2020 17:07:23 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 94E082313B for ; Sun, 13 Dec 2020 17:07:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 94E082313B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0BA3C89F2A; Sun, 13 Dec 2020 17:07:21 +0000 (UTC) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3E30A89EEB; Sun, 13 Dec 2020 17:07:18 +0000 (UTC) IronPort-SDR: p5TcyEfyvHb8xoWLydxMcMgP8X0Cp/bj8EOzKxkSPkd4Mp2aPegq1fo0BWrlvpFa4jAIgsiq7e jVOlBbFXOlhA== X-IronPort-AV: E=McAfee;i="6000,8403,9834"; a="172050583" X-IronPort-AV: E=Sophos;i="5.78,416,1599548400"; d="scan'208";a="172050583" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2020 09:07:17 -0800 IronPort-SDR: 1Bw+O7ywM7xyE6TTeFX1LAezgr2ryaZ6liwnM7TSj8WAaGP2l56jGXakH1dP8sB9qK2nmCJ0l0 PBrPY1SU/Y+w== X-IronPort-AV: E=Sophos;i="5.78,416,1599548400"; d="scan'208";a="366739089" Received: from ihazan-mobl1.ger.corp.intel.com (HELO josouza-mobl2.intel.com) ([10.255.70.79]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2020 09:07:14 -0800 From: =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [PATCH] drm/damage_helper: Check if damage clips has valid values Date: Sun, 13 Dec 2020 09:07:28 -0800 Message-Id: <20201213170728.290406-1-jose.souza@intel.com> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Deepak Rawat , Sean Paul , =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= , Gwan-gyeong Mun Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Userspace can set a damage clip with a negative coordinate, negative width or height or larger than the plane. This invalid values could cause issues in some HW or even worst enable security flaws. Cc: Gwan-gyeong Mun Cc: Sean Paul Cc: Fabio Estevam Cc: Deepak Rawat Cc: dri-devel@lists.freedesktop.org Signed-off-by: José Roberto de Souza --- drivers/gpu/drm/drm_atomic_helper.c | 4 ++- drivers/gpu/drm/drm_damage_helper.c | 49 +++++++++++++++++++++++------ include/drm/drm_damage_helper.h | 4 +-- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ba1507036f26..c6b341ecae2c 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -897,7 +897,9 @@ drm_atomic_helper_check_planes(struct drm_device *dev, drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane); - drm_atomic_helper_check_plane_damage(state, new_plane_state); + ret = drm_atomic_helper_check_plane_damage(state, new_plane_state); + if (ret) + return ret; if (!funcs || !funcs->atomic_check) continue; diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index 3a4126dc2520..9adb369440ba 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -104,36 +104,67 @@ void drm_plane_enable_fb_damage_clips(struct drm_plane *plane) EXPORT_SYMBOL(drm_plane_enable_fb_damage_clips); /** - * drm_atomic_helper_check_plane_damage - Verify plane damage on atomic_check. + * drm_atomic_helper_check_plane_damage - Verify plane damage clips on + * atomic_check. * @state: The driver state object. - * @plane_state: Plane state for which to verify damage. + * @plane_state: Plane state for which to verify damage clips. * - * This helper function makes sure that damage from plane state is discarded - * for full modeset. If there are more reasons a driver would want to do a full - * plane update rather than processing individual damage regions, then those - * cases should be taken care of here. + * This helper checks if all damage clips has valid values and makes sure that + * damage clips from plane state is discarded for full modeset. If there are + * more reasons a driver would want to do a full plane update rather than + * processing individual damage regions, then those cases should be taken care + * of here. * * Note that &drm_plane_state.fb_damage_clips == NULL in plane state means that * full plane update should happen. It also ensure helper iterator will return * &drm_plane_state.src as damage. + * + * Return: Zero on success, negative errno on failure. */ -void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, - struct drm_plane_state *plane_state) +int drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, + struct drm_plane_state *plane_state) { + struct drm_mode_rect *damaged_clips; struct drm_crtc_state *crtc_state; + unsigned int num_clips, w, h; + + num_clips = drm_plane_get_damage_clips_count(plane_state); + if (!num_clips) + return 0; if (plane_state->crtc) { crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); if (WARN_ON(!crtc_state)) - return; + return 0; if (drm_atomic_crtc_needs_modeset(crtc_state)) { drm_property_blob_put(plane_state->fb_damage_clips); plane_state->fb_damage_clips = NULL; + return 0; } } + + w = drm_rect_width(&plane_state->src) >> 16; + h = drm_rect_height(&plane_state->src) >> 16; + damaged_clips = drm_plane_get_damage_clips(plane_state); + + for (; num_clips; num_clips--, damaged_clips++) { + if (damaged_clips->x1 < 0 || damaged_clips->x2 < 0 || + damaged_clips->y1 < 0 || damaged_clips->y2 < 0) + return -EINVAL; + + if (damaged_clips->x2 < damaged_clips->x1 || + damaged_clips->y2 < damaged_clips->y1) + return -EINVAL; + + if ((damaged_clips->x2 - damaged_clips->x1) > w || + (damaged_clips->y2 - damaged_clips->y1) > h) + return -EINVAL; + } + + return 0; } EXPORT_SYMBOL(drm_atomic_helper_check_plane_damage); diff --git a/include/drm/drm_damage_helper.h b/include/drm/drm_damage_helper.h index 40c34a5bf149..5e344d1a2b22 100644 --- a/include/drm/drm_damage_helper.h +++ b/include/drm/drm_damage_helper.h @@ -65,8 +65,8 @@ struct drm_atomic_helper_damage_iter { }; void drm_plane_enable_fb_damage_clips(struct drm_plane *plane); -void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, - struct drm_plane_state *plane_state); +int drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, + struct drm_plane_state *plane_state); int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned int flags, unsigned int color, struct drm_clip_rect *clips,