From 64e15c36d6c1c57dc2d95a3f163bc830a469fc20 Mon Sep 17 00:00:00 2001 From: Dhaval Patel Date: Tue, 22 Mar 2016 22:56:38 -0700 Subject: msm: mdss: validate layer count before copying userdata Validate input layer count in rotator and async update ioctl call before copying the rotator request list and async update layer list. Change-Id: I3489e5a2d4237a47bddf56c2f44c9e3001f0b2b4 Signed-off-by: Dhaval Patel --- drivers/video/msm/mdss/mdss_compat_utils.c | 6 +++--- drivers/video/msm/mdss/mdss_fb.c | 6 +++--- drivers/video/msm/mdss/mdss_fb.h | 3 +-- drivers/video/msm/mdss/mdss_mdp.h | 4 +++- drivers/video/msm/mdss/mdss_rotator.c | 20 +++++++++++++++++--- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_compat_utils.c b/drivers/video/msm/mdss/mdss_compat_utils.c index 3bc5de6..e391a5a 100644 --- a/drivers/video/msm/mdss/mdss_compat_utils.c +++ b/drivers/video/msm/mdss/mdss_compat_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * Copyright (C) 1994 Martin Schaller * * 2001 - Documented with DocBook @@ -445,8 +445,8 @@ static int __compat_async_position_update(struct fb_info *info, update_pos.input_layer_cnt = update_pos32.input_layer_cnt; layer_cnt = update_pos32.input_layer_cnt; - if (!layer_cnt) { - pr_err("no async layer to update\n"); + if ((!layer_cnt) || (layer_cnt > MAX_LAYER_COUNT)) { + pr_err("invalid async layers :%d to update\n", layer_cnt); return -EINVAL; } diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 73ab61e..9aa87d0 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -2,7 +2,7 @@ * Core MDSS framebuffer driver. * * Copyright (C) 2007 Google Incorporated - * Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -3781,8 +3781,8 @@ static int mdss_fb_async_position_update_ioctl(struct fb_info *info, input_layer_list = update_pos.input_layers; layer_cnt = update_pos.input_layer_cnt; - if (!layer_cnt) { - pr_err("no async layers to update\n"); + if ((!layer_cnt) || (layer_cnt > MAX_LAYER_COUNT)) { + pr_err("invalid async layers :%d to update\n", layer_cnt); return -EINVAL; } diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h index 9bb8b40..f4825e3 100644 --- a/drivers/video/msm/mdss/mdss_fb.h +++ b/drivers/video/msm/mdss/mdss_fb.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -56,7 +56,6 @@ #define MDP_PP_AD_BL_LINEAR 0x0 #define MDP_PP_AD_BL_LINEAR_INV 0x1 -#define MAX_LAYER_COUNT 0xC /** * enum mdp_notify_event - Different frame events to indicate frame update state diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h index b2083c5..40ec88c 100644 --- a/drivers/video/msm/mdss/mdss_mdp.h +++ b/drivers/video/msm/mdss/mdss_mdp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -83,6 +83,8 @@ #define XIN_HALT_TIMEOUT_US 0x4000 +#define MAX_LAYER_COUNT 0xC + /* hw cursor can only be setup in highest mixer stage */ #define HW_CURSOR_STAGE(mdata) \ (((mdata)->max_target_zorder + MDSS_MDP_STAGE_0) - 1) diff --git a/drivers/video/msm/mdss/mdss_rotator.c b/drivers/video/msm/mdss/mdss_rotator.c index 86e3665..e3c46fc 100644 --- a/drivers/video/msm/mdss/mdss_rotator.c +++ b/drivers/video/msm/mdss/mdss_rotator.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2129,6 +2129,7 @@ static int mdss_rotator_handle_request(struct mdss_rot_mgr *mgr, struct mdp_rotation_item *items = NULL; struct mdss_rot_entry_container *req = NULL; int size, ret; + uint32_t req_count; ret = copy_from_user(&user_req, (void __user *)arg, sizeof(user_req)); @@ -2137,12 +2138,18 @@ static int mdss_rotator_handle_request(struct mdss_rot_mgr *mgr, return ret; } + req_count = user_req.count; + if ((!req_count) || (req_count > MAX_LAYER_COUNT)) { + pr_err("invalid rotator req count :%d\n", req_count); + return -EINVAL; + } + /* * here, we make a copy of the items so that we can copy * all the output fences to the client in one call. Otherwise, * we will have to call multiple copy_to_user */ - size = sizeof(struct mdp_rotation_item) * user_req.count; + size = sizeof(struct mdp_rotation_item) * req_count; items = devm_kzalloc(&mgr->pdev->dev, size, GFP_KERNEL); if (!items) { pr_err("fail to allocate rotation items\n"); @@ -2281,6 +2288,7 @@ static int mdss_rotator_handle_request32(struct mdss_rot_mgr *mgr, struct mdp_rotation_item *items = NULL; struct mdss_rot_entry_container *req = NULL; int size, ret; + uint32_t req_count; ret = copy_from_user(&user_req32, (void __user *)arg, sizeof(user_req32)); @@ -2289,7 +2297,13 @@ static int mdss_rotator_handle_request32(struct mdss_rot_mgr *mgr, return ret; } - size = sizeof(struct mdp_rotation_item) * user_req32.count; + req_count = user_req32.count; + if ((!req_count) || (req_count > MAX_LAYER_COUNT)) { + pr_err("invalid rotator req count :%d\n", req_count); + return -EINVAL; + } + + size = sizeof(struct mdp_rotation_item) * req_count; items = devm_kzalloc(&mgr->pdev->dev, size, GFP_KERNEL); if (!items) { pr_err("fail to allocate rotation items\n"); -- cgit v1.1