2016-12-04 06:16:14

by Pan Bian

[permalink] [raw]
Subject: [PATCH 1/1] mtd: ubi: fix improper return value

From: Pan Bian <[email protected]>

When __vmalloc() returns a NULL pointer, the region is not checked, and
we cannot make sure that only 0xFF bytes are present at offset. Thus,
returning 0 seems improper.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=189081

Signed-off-by: Pan Bian <[email protected]>
---
drivers/mtd/ubi/io.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index b6fb8f9..b54fe05 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -1413,7 +1413,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
if (!buf) {
ubi_err(ubi, "cannot allocate memory to check for 0xFFs");
- return 0;
+ return -ENOMEM;
}

err = mtd_read(ubi->mtd, addr, len, &read, buf);
--
1.9.1



2016-12-04 15:38:02

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH 1/1] mtd: ubi: fix improper return value

On 12/04/2016 07:12 AM, Pan Bian wrote:
> From: Pan Bian <[email protected]>
>
> When __vmalloc() returns a NULL pointer, the region is not checked, and
> we cannot make sure that only 0xFF bytes are present at offset. Thus,
> returning 0 seems improper.
>
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=189081
>
> Signed-off-by: Pan Bian <[email protected]>
> ---
> drivers/mtd/ubi/io.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> index b6fb8f9..b54fe05 100644
> --- a/drivers/mtd/ubi/io.c
> +++ b/drivers/mtd/ubi/io.c
> @@ -1413,7 +1413,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
> buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
> if (!buf) {
> ubi_err(ubi, "cannot allocate memory to check for 0xFFs");
> - return 0;
> + return -ENOMEM;

I wonder if you shouldn't also nuke the ubi_err() , because when you run
out of memory, printk() will likely also fail.

> }
>
> err = mtd_read(ubi->mtd, addr, len, &read, buf);
>


--
Best regards,
Marek Vasut

2016-12-04 20:33:45

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH 1/1] mtd: ubi: fix improper return value

On Sun, 2016-12-04 at 13:48 +0100, Marek Vasut wrote:
> On 12/04/2016 07:12 AM, Pan Bian wrote:
> > From: Pan Bian <[email protected]>
> >
> > When __vmalloc() returns a NULL pointer, the region is not checked, and
> > we cannot make sure that only 0xFF bytes are present at offset. Thus,
> > returning 0 seems improper.
> >
> > Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=189081
> >
> > Signed-off-by: Pan Bian <[email protected]>
> > ---
> > drivers/mtd/ubi/io.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
[]
> > @@ -1413,7 +1413,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
> > buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
> > if (!buf) {
> > ubi_err(ubi, "cannot allocate memory to check for 0xFFs");
> > - return 0;
> > + return -ENOMEM;
>
> I wonder if you shouldn't also nuke the ubi_err() , because when you run
> out of memory, printk() will likely also fail.

No, not really. printk doesn't allocate memory.

But the ubi_err should be removed because all memory
allocations that fail without a specific GFP_NOWARN
flag already have a dump_stack() call.

2016-12-04 20:52:26

by Richard Weinberger

[permalink] [raw]
Subject: Re: [PATCH 1/1] mtd: ubi: fix improper return value

On 04.12.2016 21:33, Joe Perches wrote:
>>> diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> []
>>> @@ -1413,7 +1413,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
>>> buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
>>> if (!buf) {
>>> ubi_err(ubi, "cannot allocate memory to check for 0xFFs");
>>> - return 0;
>>> + return -ENOMEM;
>>
>> I wonder if you shouldn't also nuke the ubi_err() , because when you run
>> out of memory, printk() will likely also fail.
>
> No, not really. printk doesn't allocate memory.
>
> But the ubi_err should be removed because all memory
> allocations that fail without a specific GFP_NOWARN
> flag already have a dump_stack() call.

We should better think about how to get ubi_self_check_all_ff() fixed.
When enabled on a modern NAND, vmalloc() is likely to fail now and then
since len is the erase block size and can be up to a few mega bytes.

Thanks,
//richard

2016-12-04 21:37:00

by Marek Vasut

[permalink] [raw]
Subject: Re: [PATCH 1/1] mtd: ubi: fix improper return value

On 12/04/2016 09:33 PM, Joe Perches wrote:
> On Sun, 2016-12-04 at 13:48 +0100, Marek Vasut wrote:
>> On 12/04/2016 07:12 AM, Pan Bian wrote:
>>> From: Pan Bian <[email protected]>
>>>
>>> When __vmalloc() returns a NULL pointer, the region is not checked, and
>>> we cannot make sure that only 0xFF bytes are present at offset. Thus,
>>> returning 0 seems improper.
>>>
>>> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=189081
>>>
>>> Signed-off-by: Pan Bian <[email protected]>
>>> ---
>>> drivers/mtd/ubi/io.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> []
>>> @@ -1413,7 +1413,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
>>> buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
>>> if (!buf) {
>>> ubi_err(ubi, "cannot allocate memory to check for 0xFFs");
>>> - return 0;
>>> + return -ENOMEM;
>>
>> I wonder if you shouldn't also nuke the ubi_err() , because when you run
>> out of memory, printk() will likely also fail.
>
> No, not really. printk doesn't allocate memory.
>
> But the ubi_err should be removed because all memory
> allocations that fail without a specific GFP_NOWARN
> flag already have a dump_stack() call.

Ah, thanks for the correction :-)

--
Best regards,
Marek Vasut

2016-12-05 07:09:45

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH 1/1] mtd: ubi: fix improper return value

On Sun, 2016-12-04 at 21:52 +0100, Richard Weinberger wrote:
> We should better think about how to get ubi_self_check_all_ff()
> fixed.
> When enabled on a modern NAND, vmalloc() is likely to fail now and
> then
> since len is the erase block size and can be up to a few mega bytes.

I did an attempt to switch from virtually continuous buffers to an
array of page pointers, but never finished.

2016-12-05 08:23:45

by Boris Brezillon

[permalink] [raw]
Subject: Re: [PATCH 1/1] mtd: ubi: fix improper return value

On Mon, 05 Dec 2016 09:09:34 +0200
Artem Bityutskiy <[email protected]> wrote:

> On Sun, 2016-12-04 at 21:52 +0100, Richard Weinberger wrote:
> > We should better think about how to get ubi_self_check_all_ff()
> > fixed.
> > When enabled on a modern NAND, vmalloc() is likely to fail now and
> > then
> > since len is the erase block size and can be up to a few mega bytes.
>
> I did an attempt to switch from virtually continuous buffers to an
> array of page pointers, but never finished.

I started to implement that too but unfortunately never had the time to
finish it :-(.
Don't know why you were trying to move to kzalloc-ed buffer, but my
goal was to avoid the extra copy when the controller transfers data
using DMA, and the recent posts regarding vmalloc-ed buffers and DMA
might solve the issue.

This being said, UBI and UBIFS tend to allocate big portions of
memory (usually a full eraseblock), and sometime this is
overkill.
For example, I'm not sure we need to allocate that much memory to do
things like 'check if this portion is all filled with 0xff'. Allocating
a ->max_write_size buffer and iterating over write-units should be
almost as efficient and still consume less memory. But this has nothing
to do with the vmalloc vs kmalloc debate ;-).

2016-12-05 09:50:23

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH 1/1] mtd: ubi: fix improper return value

On Mon, 2016-12-05 at 09:23 +0100, Boris Brezillon wrote:
> I started to implement that too but unfortunately never had the time
> to
> finish it :-(.
> Don't know why you were trying to move to kzalloc-ed buffer, but my
> goal was to avoid the extra copy when the controller transfers data
> using DMA, and the recent posts regarding vmalloc-ed buffers and DMA
> might solve the issue.

Yes, I wanted to do that globally for UBI/UBIFS to get rid of vmalloc.

> This being said, UBI and UBIFS tend to allocate big portions of
> memory (usually a full eraseblock), and sometime this is
> overkill.

Those checks were just hacky debugging functions at the beginning, then
they got cleaned up without a re-write.

> For example, I'm not sure we need to allocate that much memory to do
> things like 'check if this portion is all filled with 0xff'.

Because memcmp() is was very easy to use. Back then the focus was
getting other things work well, and efforts were saved on less
important parts. And 128KiB was not terribly bad. Today, these less
important things are important.

> Allocating
> a ->max_write_size buffer and iterating over write-units should be
> almost as efficient and still consume less memory. But this has
> nothing
> to do with the vmalloc vs kmalloc debate ;-).

Well, this is related. Someone may start small and take care of these
first :-)

Artem.