All of lore.kernel.org
 help / color / mirror / Atom feed
From: Waqar Hameed <waqar.hameed@axis.com>
To: Zhihao Cheng <chengzhihao1@huawei.com>
Cc: Richard Weinberger <richard@nod.at>,
	Sascha Hauer <s.hauer@pengutronix.de>, <kernel@axis.com>,
	<linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH RFC] ubifs: Fix use-after-free in ubifs_tnc_end_commit
Date: Thu, 17 Oct 2024 20:36:00 +0200	[thread overview]
Message-ID: <pnd7ca6wp9r.fsf@axis.com> (raw)
In-Reply-To: <239af2ee-c18d-414f-099f-2c82f98d9671@huawei.com> (Zhihao Cheng's message of "Wed, 16 Oct 2024 10:11:46 +0800")

On Wed, Oct 16, 2024 at 10:11 +0800 Zhihao Cheng <chengzhihao1@huawei.com> wrote:

[...]

> BTW, what is the configuration of your flash?(eg. erase size, page size)?

$ mtdinfo /dev/mtd2
  mtd2
  Name:                           firmware
  Type:                           nand
  Eraseblock size:                131072 bytes, 128.0 KiB
  Amount of eraseblocks:          1832 (240123904 bytes, 229.0 MiB)
  Minimum input/output unit size: 2048 bytes
  Sub-page size:                  2048 bytes
  OOB size:                       64 bytes
  Character device major/minor:   90:4
  Bad blocks are allowed:         true
  Device is writable:             true

$ ubinfo /dev/ubi0_0
  Volume ID:   0 (on ubi0)
  Type:        dynamic
  Alignment:   1
  Size:        661 LEBs (83931136 bytes, 80.0 MiB)
  State:       OK
  Name:        test-vol
  Character device major/minor: 244:1

[...]

> Well, let's do a preliminary analysis.
> The znode->cparent[znode->ciip] is a freed address in write_index(), which
> means:
> 1. 'znode->ciip' is valid, znode->cparent is freed by tnc_delete, however znode
> cannot be freed if znode->cnext is not NULL, which means:
>   a) 'znode->cparent' is not dirty, we should add an assertion like
>   ubifs_assert(c, ubifs_zn_dirty(znode->cparent)) in get_znodes_to_commit().
>   Note, please check that 'znode->cparent' is not NULL before the assertion.
>   b) 'znode->cparent' is dirty, but it is not added into list 'c->cnext', we
>   should traverse the entire TNC in get_znodes_to_commit() to make sure that all
>   dirty znodes are collected into list 'c->cnext', so another assertion is
>  needed.
> 2. 'znode->ciip' is invalid, and the value beyonds the memory area of
> znode->cparent. All znodes are allocated with size of 'c->max_znode_sz', which
> means that 'znode->ciip' exceeds the 'c->fantout', so we can add an assertion
> like ubifs_assert(c, znode->ciip < c->fantout) in get_znodes_to_commit().
>
> That's what I can think of, are there any other possibilities?

I looked a little more at `get_znodes_to_commit()` when adding the
asserts you suggest, and I have a question: what happens when
`find_next_dirty()` returns `NULL`? In that case

```
znode->cnext = c->cnext;
```

but `znode->cparent` and `znode->ciip` are not updated. Shouldn't they?

By the way, I left a test running, and it actually triggered the same
KASAN report after 800 iterations... So we now at least know that this
patch doesn't indeed fix the problem.

I also found another minor thing regarding the update of `cnt` in
`get_znodes_to_commit`. I'll send a separate patch for that.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

WARNING: multiple messages have this Message-ID (diff)
From: Waqar Hameed <waqar.hameed@axis.com>
To: Zhihao Cheng <chengzhihao1@huawei.com>
Cc: Richard Weinberger <richard@nod.at>,
	Sascha Hauer <s.hauer@pengutronix.de>, <kernel@axis.com>,
	<linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH RFC] ubifs: Fix use-after-free in ubifs_tnc_end_commit
Date: Thu, 17 Oct 2024 20:36:00 +0200	[thread overview]
Message-ID: <pnd7ca6wp9r.fsf@axis.com> (raw)
In-Reply-To: <239af2ee-c18d-414f-099f-2c82f98d9671@huawei.com> (Zhihao Cheng's message of "Wed, 16 Oct 2024 10:11:46 +0800")

On Wed, Oct 16, 2024 at 10:11 +0800 Zhihao Cheng <chengzhihao1@huawei.com> wrote:

[...]

> BTW, what is the configuration of your flash?(eg. erase size, page size)?

$ mtdinfo /dev/mtd2
  mtd2
  Name:                           firmware
  Type:                           nand
  Eraseblock size:                131072 bytes, 128.0 KiB
  Amount of eraseblocks:          1832 (240123904 bytes, 229.0 MiB)
  Minimum input/output unit size: 2048 bytes
  Sub-page size:                  2048 bytes
  OOB size:                       64 bytes
  Character device major/minor:   90:4
  Bad blocks are allowed:         true
  Device is writable:             true

$ ubinfo /dev/ubi0_0
  Volume ID:   0 (on ubi0)
  Type:        dynamic
  Alignment:   1
  Size:        661 LEBs (83931136 bytes, 80.0 MiB)
  State:       OK
  Name:        test-vol
  Character device major/minor: 244:1

[...]

> Well, let's do a preliminary analysis.
> The znode->cparent[znode->ciip] is a freed address in write_index(), which
> means:
> 1. 'znode->ciip' is valid, znode->cparent is freed by tnc_delete, however znode
> cannot be freed if znode->cnext is not NULL, which means:
>   a) 'znode->cparent' is not dirty, we should add an assertion like
>   ubifs_assert(c, ubifs_zn_dirty(znode->cparent)) in get_znodes_to_commit().
>   Note, please check that 'znode->cparent' is not NULL before the assertion.
>   b) 'znode->cparent' is dirty, but it is not added into list 'c->cnext', we
>   should traverse the entire TNC in get_znodes_to_commit() to make sure that all
>   dirty znodes are collected into list 'c->cnext', so another assertion is
>  needed.
> 2. 'znode->ciip' is invalid, and the value beyonds the memory area of
> znode->cparent. All znodes are allocated with size of 'c->max_znode_sz', which
> means that 'znode->ciip' exceeds the 'c->fantout', so we can add an assertion
> like ubifs_assert(c, znode->ciip < c->fantout) in get_znodes_to_commit().
>
> That's what I can think of, are there any other possibilities?

I looked a little more at `get_znodes_to_commit()` when adding the
asserts you suggest, and I have a question: what happens when
`find_next_dirty()` returns `NULL`? In that case

```
znode->cnext = c->cnext;
```

but `znode->cparent` and `znode->ciip` are not updated. Shouldn't they?

By the way, I left a test running, and it actually triggered the same
KASAN report after 800 iterations... So we now at least know that this
patch doesn't indeed fix the problem.

I also found another minor thing regarding the update of `cnt` in
`get_znodes_to_commit`. I'll send a separate patch for that.

  reply	other threads:[~2024-10-17 18:36 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-09 14:46 [PATCH RFC] ubifs: Fix use-after-free in ubifs_tnc_end_commit Waqar Hameed
2024-10-09 14:46 ` Waqar Hameed
2024-10-12 12:30 ` Zhihao Cheng
2024-10-12 12:30   ` Zhihao Cheng
2024-10-15 18:52   ` Waqar Hameed
2024-10-15 18:52     ` Waqar Hameed
2024-10-16  2:11     ` Zhihao Cheng
2024-10-16  2:11       ` Zhihao Cheng
2024-10-17 18:36       ` Waqar Hameed [this message]
2024-10-17 18:36         ` Waqar Hameed
2024-10-18  1:40         ` Zhihao Cheng
2024-10-18  1:40           ` Zhihao Cheng
2024-11-06 16:36           ` Waqar Hameed
2024-11-06 16:36             ` Waqar Hameed
2024-11-07  7:14             ` Zhihao Cheng
2024-11-07  7:14               ` Zhihao Cheng
2024-11-07 22:11               ` Waqar Hameed
2024-11-07 22:11                 ` Waqar Hameed
2024-10-29  8:10 ` Ryder Wang
2024-10-29  8:10   ` Ryder Wang
2024-10-29  9:06   ` Zhihao Cheng
2024-10-29  9:06     ` Zhihao Cheng
2024-10-29  9:56     ` Ryder Wang
2024-10-29  9:56       ` Ryder Wang
2024-10-29 11:19       ` Zhihao Cheng
2024-10-29 11:19         ` Zhihao Cheng
2024-11-07  8:39 ` Zhihao Cheng
2024-11-07  8:39   ` Zhihao Cheng
2024-11-07 22:38   ` Waqar Hameed
2024-11-07 22:38     ` Waqar Hameed
2024-11-08  1:38     ` Zhihao Cheng
2024-11-08  1:38       ` Zhihao Cheng
2024-11-08 18:02     ` Waqar Hameed
2024-11-08 18:02       ` Waqar Hameed

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=pnd7ca6wp9r.fsf@axis.com \
    --to=waqar.hameed@axis.com \
    --cc=chengzhihao1@huawei.com \
    --cc=kernel@axis.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=richard@nod.at \
    --cc=s.hauer@pengutronix.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.