UBI leb_write_unlock NULL pointer Oops (continuation)

Richard Weinberger richard at nod.at
Wed Mar 5 15:57:42 EST 2014


Am 24.02.2014 16:48, schrieb Bill Pringlemeir:
> On 24 Feb 2014, bpringlemeir at nbsps.com wrote:
> 
>> /* could reschedule here... */
>> on 'if (vol->eba_tbl[lnum] != from)' another thread has this
>> 'ltree_entry' so count is >1.
>> /* could reschedule here... */
> 
> Sorry, maybe that is not true.  I don't know enough about the logic of
> ubi_eba_copy_leb().  Another thread has at least changed the physical
> map.  It may/may not still have the rwsemaphore.

Thorsten and Emanuel from Lawo AG kindly gave me access to one of their boards
such that I was able to work directly on the issue.

The solution is rather trivial.
Two commits were missing in their tree:

commit 8afd500cb52a5d00bab4525dd5a560d199f979b9
Author: Adam Thomas <adamthomas1111 at gmail.com>
Date:   Sat Feb 2 22:35:08 2013 +0000

    UBIFS: fix double free of ubifs_orphan objects

and

commit 2928f0d0c5ebd6c9605c0d98207a44376387c298
Author: Adam Thomas <adamthomas1111 at gmail.com>
Date:   Sat Feb 2 22:32:31 2013 +0000

    UBIFS: fix use of freed ubifs_orphan objects

Bill, I'm very sure this fixes also the issue you face.

It is not obvious that these two commits fix the issue.
I've spend some time to figure out what exactly happens.

In most cases up_write() crashes because "waiter" in __rwsem_do_wake()
or __rwsem_wake_one_writer() somehow became NULL.
It turned out that sem->wait_list gets overwritten.

"UBIFS: fix double free of ubifs_orphan objects" fixes more than a double free.
It addresses an issue where an orphan stays too long on the orphan list and therefore could
be free()'ed twice. But another issue is that in ubifs_orphan_start_commit()
an already free()'ed is set to NULL.
Namely by the line "*last = NULL;".
This is the line of code where the memory corruption happens.
I've double checked it by adding a few trace_printk() and BUG_ON().

Thanks,
//richard



More information about the linux-mtd mailing list