From 7c806883e143dc60439e6bdb3589700ebed1efaa Mon Sep 17 00:00:00 2001 From: ZhengShunQian Date: Wed, 30 Sep 2015 13:33:56 +0100 Subject: nvmem: core: fix the out-of-range leak in read/write() The position to read/write must be less than max register size. Signed-off-by: ZhengShunQian Acked-by: Srinivas Kandagatla Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/nvmem') diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index d3c6676b3c0c..f4af8e5fcd94 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -67,7 +67,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, int rc; /* Stop the user from reading */ - if (pos > nvmem->size) + if (pos >= nvmem->size) return 0; if (pos + count > nvmem->size) @@ -92,7 +92,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, int rc; /* Stop the user from writing */ - if (pos > nvmem->size) + if (pos >= nvmem->size) return 0; if (pos + count > nvmem->size) -- cgit From cbf854ab36870b931aeba4edd954015b7c3005a2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 30 Sep 2015 13:35:15 +0100 Subject: nvmem: core: Handle shift bits in-place if cell->nbits is non-zero It's pointless to test (cell->bit_offset || cell->bit_offset). nvmem_shift_read_buffer_in_place() should be called when (cell->bit_offset || cell->nbits). Signed-off-by: Axel Lin Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/nvmem') diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index f4af8e5fcd94..676607cb01bb 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -825,7 +825,7 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, return rc; /* shift bits in-place */ - if (cell->bit_offset || cell->bit_offset) + if (cell->bit_offset || cell->nbits) nvmem_shift_read_buffer_in_place(cell, buf); *len = cell->bytes; -- cgit From ace22170655f61d82fff95e57d673bf847a32a03 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 30 Sep 2015 13:36:10 +0100 Subject: nvmem: core: Fix memory leak in nvmem_cell_write A tmp buffer is allocated if cell->bit_offset || cell->nbits. So the tmp buffer needs to be freed at the same condition to avoid leak. Signed-off-by: Axel Lin Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/nvmem') diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 676607cb01bb..6fd4e5a5ef4a 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -938,7 +938,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) rc = regmap_raw_write(nvmem->regmap, cell->offset, buf, cell->bytes); /* free the tmp buffer */ - if (cell->bit_offset) + if (cell->bit_offset || cell->nbits) kfree(buf); if (IS_ERR_VALUE(rc)) -- cgit From fb727077b04f768d0c79d9aa29e958262a9e3d9e Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 30 Sep 2015 13:36:31 +0100 Subject: nvmem: sunxi: Check for memory allocation failure The sunxi_sid driver doesn't check for kmalloc return status before derefencing the returned pointer, which could lead to a NULL pointer dereference if kmalloc failed. Check for its return code to make sure it deosn't happen. Reported-by: Dan Carpenter Signed-off-by: Maxime Ripard Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/sunxi_sid.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/nvmem') diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c index 14777dd5212d..cfa3b85064dd 100644 --- a/drivers/nvmem/sunxi_sid.c +++ b/drivers/nvmem/sunxi_sid.c @@ -103,7 +103,7 @@ static int sunxi_sid_probe(struct platform_device *pdev) struct nvmem_device *nvmem; struct regmap *regmap; struct sunxi_sid *sid; - int i, size; + int ret, i, size; char *randomness; sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL); @@ -131,6 +131,11 @@ static int sunxi_sid_probe(struct platform_device *pdev) return PTR_ERR(nvmem); randomness = kzalloc(sizeof(u8) * size, GFP_KERNEL); + if (!randomness) { + ret = -EINVAL; + goto err_unreg_nvmem; + } + for (i = 0; i < size; i++) randomness[i] = sunxi_sid_read_byte(sid, i); @@ -140,6 +145,10 @@ static int sunxi_sid_probe(struct platform_device *pdev) platform_set_drvdata(pdev, nvmem); return 0; + +err_unreg_nvmem: + nvmem_unregister(nvmem); + return ret; } static int sunxi_sid_remove(struct platform_device *pdev) -- cgit