From patchwork Tue May 9 14:42:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Pundir X-Patchwork-Id: 98936 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp1857702qge; Tue, 9 May 2017 07:43:50 -0700 (PDT) X-Received: by 10.84.204.8 with SMTP id a8mr726374ple.4.1494341029975; Tue, 09 May 2017 07:43:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494341029; cv=none; d=google.com; s=arc-20160816; b=0Lx/OcPXNhnwJJ+SPqzJPuUIjSny/91vgqnX3SttJlPvPkDEXs8i+1yT0XoOy94XEF yzw/667j+ho+y5lGr+IavY9zzhYCWdpleIdK//fjHpXyO5elbvIok8yA2GDNCFGsmfhG RDsutTngfzjC2Y1yCtK0JZF0cAGvTLF+MfDOw/szpXZU9zcERO7YsWXHYuOzXLEi238F XFd2gPMP3lMqm95ScIBBexRxFdzr7SvpcOsyrp5jnqdTLyaa5aLazYhLotzZ/2spq6vA MfsG/9HprrwMxXruACBNluNmn57JjxNNdkh2Dsx77GaLbK2hMr7F80LDAwUzwvWM8zeM tanw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=6xSUeRQ/qeuJ007DPp5HDhkIJMAqcR1rwQK8TwJD8po=; b=p8EAO7RRNJuokvajcgY+qWyJJEueBo0ZTj1vePa1u5ZJ12+ojnTptW/PCkMAhG3elV sX6Wkex62WsHo0tOFflIrvw0foO+SeDq67gE53bR9Bye7vbsLlDvLZ+pRwN4HLe6XVp6 muCEV5R7z2QdMy87Xr4LOPRxPbBW0n/LQRS7D9R6BhdtLU8qglcpwrHwCtyIhSLA9H1K sSsLa2JetahS3e8wlmRNG8Sm04h8ytKJPYyK1ZvJMPyE7KtBZdBX6H/whUdAZLkB0hpQ zJcNaNK+IuvICNI96+bwllFw22lLS5GoFMafRHB+slIQyNlccgm9tgO7wqQ+Nbu+53AO tcUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h2si99892pli.322.2017.05.09.07.43.49; Tue, 09 May 2017 07:43:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753228AbdEIOnt (ORCPT + 6 others); Tue, 9 May 2017 10:43:49 -0400 Received: from mail-pf0-f182.google.com ([209.85.192.182]:33692 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754280AbdEIOns (ORCPT ); Tue, 9 May 2017 10:43:48 -0400 Received: by mail-pf0-f182.google.com with SMTP id e193so1211629pfh.0 for ; Tue, 09 May 2017 07:43:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6xSUeRQ/qeuJ007DPp5HDhkIJMAqcR1rwQK8TwJD8po=; b=QCXvWJgtrnZ+66JoIh6BZUIjaWrbrhdCCeJ8cgoxD6mEu688ingay8IWkImz8UXI6f A6RB5B6uwKUaQmJRxqHnqoJEP21I0RR+mXli7WTbl2/esXxC5i5LL3cStXrJXbOxLOX6 taF8M1OPqxVD5/iaqphGed9Mo3X1Vg794x2vc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6xSUeRQ/qeuJ007DPp5HDhkIJMAqcR1rwQK8TwJD8po=; b=DVNBp7J0PLAmvqVUwE23s1f4RdoYQO5afmi+xm79R8azhvUhLrZ5HV0+f1VeRluCny n0Qrj4cJR0vdaDbQAgK8VyUDi+RW8ghMG/JzithdQvbDIoZdziAWSR2FF6ZTb/teWAfE A6GKZD2TOCA9dbaQ3Dgq2oLZE2F5sukV/sXFDIQe2KqjdC25FjmXFSetSgnQSYam5ieh hp535zvekSKRX5pUNr4N4jkZ3nZniUX0/j/WiPTTqiLR1mM5/t4m6t1CgvS4ci2OSeZr sFYQvQY2wEZFR+1X+79pz4ZefEetlNhw7cjJ3l66DAz8qipKFIjw1XgaOFFCHlVfNvhC hM2g== X-Gm-Message-State: AODbwcBTJY3pMeh4E/BvDbmIox5SBNoif0516dLF7Xy4d1v7LgBkBn8N JSs34VZ/6BavcatH X-Received: by 10.84.224.140 with SMTP id s12mr631987plj.169.1494341027716; Tue, 09 May 2017 07:43:47 -0700 (PDT) Received: from localhost.localdomain ([106.51.135.126]) by smtp.gmail.com with ESMTPSA id 11sm341811pfj.59.2017.05.09.07.43.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 May 2017 07:43:47 -0700 (PDT) From: Amit Pundir To: Greg KH Cc: stable@vger.kernel.org, Takashi Iwai , Mauro Carvalho Chehab Subject: [PATCH for-3.18 23/24] xc2028: Fix use-after-free bug properly Date: Tue, 9 May 2017 20:12:47 +0530 Message-Id: <1494340968-17152-24-git-send-email-amit.pundir@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494340968-17152-1-git-send-email-amit.pundir@linaro.org> References: <1494340968-17152-1-git-send-email-amit.pundir@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Takashi Iwai commit 22a1e7783e173ab3d86018eb590107d68df46c11 upstream. The commit 8dfbcc4351a0 ("[media] xc2028: avoid use after free") tried to address the reported use-after-free by clearing the reference. However, it's clearing the wrong pointer; it sets NULL to priv->ctrl.fname, but it's anyway overwritten by the next line memcpy(&priv->ctrl, p, sizeof(priv->ctrl)). OTOH, the actual code accessing the freed string is the strcmp() call with priv->fname: if (!firmware_name[0] && p->fname && priv->fname && strcmp(p->fname, priv->fname)) free_firmware(priv); where priv->fname points to the previous file name, and this was already freed by kfree(). For fixing the bug properly, this patch does the following: - Keep the copy of firmware file name in only priv->fname, priv->ctrl.fname isn't changed; - The allocation is done only when the firmware gets loaded; - The kfree() is called in free_firmware() commonly Fixes: commit 8dfbcc4351a0 ('[media] xc2028: avoid use after free') Cc: Signed-off-by: Takashi Iwai Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Amit Pundir --- drivers/media/tuners/tuner-xc2028.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) -- 2.7.4 diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 0b54ec2d6eed..9948578df228 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -281,6 +281,14 @@ static void free_firmware(struct xc2028_data *priv) int i; tuner_dbg("%s called\n", __func__); + /* free allocated f/w string */ + if (priv->fname != firmware_name) + kfree(priv->fname); + priv->fname = NULL; + + priv->state = XC2028_NO_FIRMWARE; + memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); + if (!priv->firm) return; @@ -291,9 +299,6 @@ static void free_firmware(struct xc2028_data *priv) priv->firm = NULL; priv->firm_size = 0; - priv->state = XC2028_NO_FIRMWARE; - - memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); } static int load_all_firmwares(struct dvb_frontend *fe, @@ -884,9 +889,8 @@ read_not_reliable: return 0; fail: - priv->state = XC2028_NO_FIRMWARE; + free_firmware(priv); - memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); if (retry_count < 8) { msleep(50); retry_count++; @@ -1332,11 +1336,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) mutex_lock(&xc2028_list_mutex); /* only perform final cleanup if this is the last instance */ - if (hybrid_tuner_report_instance_count(priv) == 1) { + if (hybrid_tuner_report_instance_count(priv) == 1) free_firmware(priv); - kfree(priv->ctrl.fname); - priv->ctrl.fname = NULL; - } if (priv) hybrid_tuner_release_state(priv); @@ -1399,19 +1400,8 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) /* * Copy the config data. - * For the firmware name, keep a local copy of the string, - * in order to avoid troubles during device release. */ - kfree(priv->ctrl.fname); - priv->ctrl.fname = NULL; memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); - if (p->fname) { - priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); - if (priv->ctrl.fname == NULL) { - rc = -ENOMEM; - goto unlock; - } - } /* * If firmware name changed, frees firmware. As free_firmware will @@ -1426,10 +1416,15 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) if (priv->state == XC2028_NO_FIRMWARE) { if (!firmware_name[0]) - priv->fname = priv->ctrl.fname; + priv->fname = kstrdup(p->fname, GFP_KERNEL); else priv->fname = firmware_name; + if (!priv->fname) { + rc = -ENOMEM; + goto unlock; + } + rc = request_firmware_nowait(THIS_MODULE, 1, priv->fname, priv->i2c_props.adap->dev.parent,