mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Xiubo Li <Li.Xiubo@freescale.com>
To: <broonie@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <dp@opensource.wolfsonmicro.com>,
	Xiubo Li <Li.Xiubo@freescale.com>
Subject: [PATCH 6/6] regmap: cache: Fix possible ZERO_SIZE_PTR pointer dereferencing error.
Date: Thu, 9 Oct 2014 17:02:57 +0800	[thread overview]
Message-ID: <1412845377-17134-7-git-send-email-Li.Xiubo@freescale.com> (raw)
In-Reply-To: <1412845377-17134-1-git-send-email-Li.Xiubo@freescale.com>

When all the registers are volatile(unlikely, but logically and mostly
will happen for some 'device' who has very few registers), then the
count will be euqal to 0, then kmalloc() will return ZERO_SIZE_PTR,
which equals to ((void *)16).

So this patch fix this with just doing the zero check before calling
kmalloc(). If the count == 0, so we can make sure that all the registers
are volatile, so no cache is need.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 drivers/base/regmap/regcache.c | 50 ++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index a06bcd2..f373c35 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -36,6 +36,23 @@ static int regcache_hw_init(struct regmap *map)
 	if (!map->num_reg_defaults_raw)
 		return -EINVAL;
 
+	/* calculate the size of reg_defaults */
+	for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++)
+		if (!regmap_volatile(map, i * map->reg_stride))
+			count++;
+
+	/* all registers are volatile, so just bypass */
+	if (!count) {
+		map->cache_bypass = true;
+		return 0;
+	}
+
+	map->num_reg_defaults = count;
+	map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default),
+					  GFP_KERNEL);
+	if (!map->reg_defaults)
+		return -ENOMEM;
+
 	if (!map->reg_defaults_raw) {
 		u32 cache_bypass = map->cache_bypass;
 		dev_warn(map->dev, "No cache defaults, reading back from HW\n");
@@ -43,33 +60,21 @@ static int regcache_hw_init(struct regmap *map)
 		/* Bypass the cache access till data read from HW*/
 		map->cache_bypass = 1;
 		tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL);
-		if (!tmp_buf)
-			return -ENOMEM;
+		if (!tmp_buf) {
+			ret = -ENOMEM;
+			goto err_free;
+		}
 		ret = regmap_raw_read(map, 0, tmp_buf,
 				      map->num_reg_defaults_raw);
 		map->cache_bypass = cache_bypass;
-		if (ret < 0) {
-			kfree(tmp_buf);
-			return ret;
-		}
+		if (ret < 0)
+			goto err_cache_free;
+
 		map->reg_defaults_raw = tmp_buf;
 		map->cache_free = 1;
 	}
 
-	/* calculate the size of reg_defaults */
-	for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++)
-		if (!regmap_volatile(map, i * map->reg_stride))
-			count++;
-
-	map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default),
-					  GFP_KERNEL);
-	if (!map->reg_defaults) {
-		ret = -ENOMEM;
-		goto err_free;
-	}
-
 	/* fill the reg_defaults */
-	map->num_reg_defaults = count;
 	for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
 		if (regmap_volatile(map, i * map->reg_stride))
 			continue;
@@ -81,9 +86,10 @@ static int regcache_hw_init(struct regmap *map)
 
 	return 0;
 
+err_cache_free:
+	kfree(tmp_buf);
 err_free:
-	if (map->cache_free)
-		kfree(map->reg_defaults_raw);
+	kfree(map->reg_defaults);
 
 	return ret;
 }
@@ -147,6 +153,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
 		ret = regcache_hw_init(map);
 		if (ret < 0)
 			return ret;
+		if (map->cache_bypass)
+			return 0;
 	}
 
 	if (!map->max_register)
-- 
2.1.0.27.g96db324


  parent reply	other threads:[~2014-10-09  9:04 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-09  9:02 [PATCH 0/6] regmap: cache: cleanup and fix bugs Xiubo Li
2014-10-09  9:02 ` [PATCH 1/6] regmap: cache: Sort include headers alphabetically Xiubo Li
2014-10-13 10:39   ` Mark Brown
2014-10-09  9:02 ` [PATCH 2/6] regmap: cache: cleanup regcache_hw_init() Xiubo Li
2014-10-13 10:47   ` Mark Brown
2014-10-14  1:52     ` Li.Xiubo
2014-10-09  9:02 ` [PATCH 3/6] regmap: cache: fix errno in regcache_hw_init() Xiubo Li
2014-10-13 10:48   ` Mark Brown
2014-10-09  9:02 ` [PATCH 4/6] regmap: cache: speed regcache_hw_init() up Xiubo Li
2014-10-13 10:48   ` Mark Brown
2014-10-09  9:02 ` [PATCH 5/6] regmap: cache: use kmalloc_array instead of kmalloc Xiubo Li
2014-10-13 10:49   ` Mark Brown
2014-10-09  9:02 ` Xiubo Li [this message]
2014-10-13 10:54   ` [PATCH 6/6] regmap: cache: Fix possible ZERO_SIZE_PTR pointer dereferencing error Mark Brown
2014-10-14  2:03     ` Li.Xiubo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1412845377-17134-7-git-send-email-Li.Xiubo@freescale.com \
    --to=li.xiubo@freescale.com \
    --cc=broonie@kernel.org \
    --cc=dp@opensource.wolfsonmicro.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®