Re: [PATCH v2] ubi: gluebi: Fix NULL pointer dereference caused by ftl notifier

Zhihao Cheng
2023-10-20T02:28:40Z

在 2023/10/20 4:27, Richard Weinberger 写道:
> ----- Ursprüngliche Mail -----
>> Von: "ZhaoLong Wang" <wangzhaolong1@huawei.com>
>> An: "richard" <richard@nod.at>, "Miquel Raynal" <miquel.raynal@bootlin.com>, "Vignesh Raghavendra" <vigneshr@ti.com>,
>> dpervushin@embeddedalley.com, "Artem Bityutskiy" <Artem.Bityutskiy@nokia.com>
>> CC: "linux-mtd" <linux-mtd@lists.infradead.org>, "linux-kernel" <linux-kernel@vger.kernel.org>, "chengzhihao1"
>> <chengzhihao1@huawei.com>, "ZhaoLong Wang" <wangzhaolong1@huawei.com>, "yi zhang" <yi.zhang@huawei.com>, "yangerkun"
>> <yangerkun@huawei.com>
>> Gesendet: Mittwoch, 18. Oktober 2023 14:16:18
>> Betreff: [PATCH v2] ubi: gluebi: Fix NULL pointer dereference caused by ftl notifier
>
>> If both flt.ko and gluebi.ko are loaded, the notiier of ftl
>> triggers NULL pointer dereference when trying to access
>> ‘gluebi->desc’ in gluebi_read().
>>
>> ubi_gluebi_init
>> ubi_register_volume_notifier
>> ubi_enumerate_volumes
>> ubi_notify_all
>> gluebi_notify nb->notifier_call()
>> gluebi_create
>> mtd_device_register
>> mtd_device_parse_register
>> add_mtd_device
>> blktrans_notify_add not->add()
>> ftl_add_mtd tr->add_mtd()
>> scan_header
>> mtd_read
>> mtd_read
>> mtd_read_oob
>> gluebi_read mtd->read()
>> gluebi->desc - NULL
>>
>> Detailed reproduction information available at the link[1],
>>
>> In the normal case, obtain gluebi->desc in the gluebi_get_device(),
>> and accesses gluebi->desc in the gluebi_read(). However,
>> gluebi_get_device() is not executed in advance in the
>> ftl_add_mtd() process, which leads to NULL pointer dereference.
>>
>> The value of gluebi->desc may also be a negative error code, which
>> triggers the page fault error.
>>
>> This patch has the following modifications:
>>
>> 1. Do not assign gluebi->desc to the error code. Use the NULL instead.
>>
>> 2. Always check the validity of gluebi->desc in gluebi_read() If the
>> gluebi->desc is NULL, try to get MTD device.
>>
>> Such a modification currently works because the mutex "mtd_table_mutex"
>> is held on all necessary paths, including the ftl_add_mtd() call path,
>> open and close paths. Therefore, many race condition can be avoided.
>
> I see the problem, but I'm not really satisfied by the solution.
> Adding this hack to gluebi_read() is not nice at all.

Yes, it's jsut a workaround. At the begining, I prefer that increasing
volume refcnt (by ubi_open_volume) in gluebi_create and releasing volume
refcnt in gluebi_remove. It looks more reasonable that holding a refcnt
of UBI volume when gluebi is alive. After looking through the code, the
creation/destroying of gluebi is triggered by volume
actions(UBI_VOLUME_ADDED/UBI_VOLUME_REMOVED), which means that:
1. gluebi_remove is depended on UBI_VOLUME_REMOVED(triggered by
ubi_remove_volume)
2. ubi_remove_volume won't be executed until the refcnt of volume
becomes 0(released by gluebi_remove)

If we add new ioctls to control creation/destroying of gluebi, then
gluebi mtd won't be automatically created when UBI volume is added. I'm
not certain whether this change will effect existing startup process
that depends on gluebi.

>
> Is there a strong reason why have to defer ubi_open_volume() to
> gluebi_get_device()?
>
> Miquel, what do you think?
>
> Thanks,
> //richard
>
> .