All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chen Zhongjin <chenzhongjin@huawei.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: <linux-nilfs@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<konishi.ryusuke@gmail.com>
Subject: Re: [PATCH] nilfs2: Fix nilfs_sufile_mark_dirty() not set segment usage as dirty
Date: Sat, 19 Nov 2022 13:28:53 +0800	[thread overview]
Message-ID: <55553de4-04c3-09f3-b075-f0112d2298cb@huawei.com> (raw)
In-Reply-To: <0e693d41-0bb5-b4a9-19b7-1c71e90e06bf@huawei.com>


On 2022/11/19 13:24, Chen Zhongjin wrote:
> On 2022/11/19 6:11, Andrew Morton wrote:
>> On Fri, 18 Nov 2022 14:33:04 +0800 Chen Zhongjin 
>> <chenzhongjin@huawei.com> wrote:
>>
>>> In nilfs_sufile_mark_dirty(), the buffer and inode are set dirty, but
>>> nilfs_segment_usage is not set dirty, which makes it can be found by
>>> nilfs_sufile_alloc() because it checks nilfs_segment_usage_clean(su).
>>>
>>> This will cause the problem reported by syzkaller:
>>> https://syzkaller.appspot.com/bug?id=c7c4748e11ffcc367cef04f76e02e931833cbd24 
>>>
>>>
>>> It's because the case starts with segbuf1.segnum = 3, nextnum = 4, and
>>> nilfs_sufile_alloc() not called to allocate a new segment.
>>>
>>> The first time nilfs_segctor_extend_segments() allocated segment
>>> segbuf2.segnum = segbuf1.nextnum = 4, then nilfs_sufile_alloc() found
>>> nextnextnum = 4 segment because its su is not set dirty.
>>> So segbuf2.nextnum = 4, which causes next segbuf3.segnum = 4.
>>>
>>> sb_getblk() will get same bh for segbuf2 and segbuf3, and this bh is
>>> added to both buffer lists of two segbuf.
>>> It makes the list head of second list linked to the first one. When
>>> iterating the first one, it will access and deref the head of second,
>>> which causes NULL pointer dereference.
>>>
>>> Fixes: 9ff05123e3bf ("nilfs2: segment constructor")
>> Merged in 2009!
>
> Yes, seems it is introduced at the beginning of this file and the 
> function called nilfs_touch_segusage().
>
> Wired that this problem is not discovered utill now. So I'm wondering 
> that whether this is a real-world
> problem or just a use case constructed maliciously by syzkaller. But 
> according to the result of syzkaller bisection,
> this problem should have a history.
>>> --- a/fs/nilfs2/sufile.c
>>> +++ b/fs/nilfs2/sufile.c
>>> @@ -495,12 +495,18 @@ void nilfs_sufile_do_free(struct inode 
>>> *sufile, __u64 segnum,
>>>   int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
>>>   {
>>>       struct buffer_head *bh;
>>> +    void *kaddr;
>>> +    struct nilfs_segment_usage *su;
>>>       int ret;
>>>         ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 
>>> 0, &bh);
>>>       if (!ret) {
>>>           mark_buffer_dirty(bh);
>>>           nilfs_mdt_mark_dirty(sufile);
>>> +        kaddr = kmap_atomic(bh->b_page);
>>> +        su = nilfs_sufile_block_get_segment_usage(sufile, segnum, 
>>> bh, kaddr);
>>> +        nilfs_segment_usage_set_dirty(su);
>>> +        kunmap_atomic(kaddr);
>>>           brelse(bh);
>>>       }
>>>       return ret;
>> Do we feel that this fix should be backported into -stable kernels?
> Sorry that I'm not familiar with the specific use scenarios of nilfs2. 
> So I can't offer a better advice. I think if it
> is a problem that not happen easily in normal situations there's no 
> necessary to backport it to stable.

I just noticed Ryusuke's mail so let's do it as his advice.

Thanks for your time!

Best,

Chen


WARNING: multiple messages have this Message-ID (diff)
From: Chen Zhongjin <chenzhongjin-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
To: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	konishi.ryusuke-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Subject: Re: [PATCH] nilfs2: Fix nilfs_sufile_mark_dirty() not set segment usage as dirty
Date: Sat, 19 Nov 2022 13:28:53 +0800	[thread overview]
Message-ID: <55553de4-04c3-09f3-b075-f0112d2298cb@huawei.com> (raw)
In-Reply-To: <0e693d41-0bb5-b4a9-19b7-1c71e90e06bf-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>


On 2022/11/19 13:24, Chen Zhongjin wrote:
> On 2022/11/19 6:11, Andrew Morton wrote:
>> On Fri, 18 Nov 2022 14:33:04 +0800 Chen Zhongjin 
>> <chenzhongjin-hv44wF8Li93QT0dZR+AlfA@public.gmane.org> wrote:
>>
>>> In nilfs_sufile_mark_dirty(), the buffer and inode are set dirty, but
>>> nilfs_segment_usage is not set dirty, which makes it can be found by
>>> nilfs_sufile_alloc() because it checks nilfs_segment_usage_clean(su).
>>>
>>> This will cause the problem reported by syzkaller:
>>> https://syzkaller.appspot.com/bug?id=c7c4748e11ffcc367cef04f76e02e931833cbd24 
>>>
>>>
>>> It's because the case starts with segbuf1.segnum = 3, nextnum = 4, and
>>> nilfs_sufile_alloc() not called to allocate a new segment.
>>>
>>> The first time nilfs_segctor_extend_segments() allocated segment
>>> segbuf2.segnum = segbuf1.nextnum = 4, then nilfs_sufile_alloc() found
>>> nextnextnum = 4 segment because its su is not set dirty.
>>> So segbuf2.nextnum = 4, which causes next segbuf3.segnum = 4.
>>>
>>> sb_getblk() will get same bh for segbuf2 and segbuf3, and this bh is
>>> added to both buffer lists of two segbuf.
>>> It makes the list head of second list linked to the first one. When
>>> iterating the first one, it will access and deref the head of second,
>>> which causes NULL pointer dereference.
>>>
>>> Fixes: 9ff05123e3bf ("nilfs2: segment constructor")
>> Merged in 2009!
>
> Yes, seems it is introduced at the beginning of this file and the 
> function called nilfs_touch_segusage().
>
> Wired that this problem is not discovered utill now. So I'm wondering 
> that whether this is a real-world
> problem or just a use case constructed maliciously by syzkaller. But 
> according to the result of syzkaller bisection,
> this problem should have a history.
>>> --- a/fs/nilfs2/sufile.c
>>> +++ b/fs/nilfs2/sufile.c
>>> @@ -495,12 +495,18 @@ void nilfs_sufile_do_free(struct inode 
>>> *sufile, __u64 segnum,
>>>   int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
>>>   {
>>>       struct buffer_head *bh;
>>> +    void *kaddr;
>>> +    struct nilfs_segment_usage *su;
>>>       int ret;
>>>         ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 
>>> 0, &bh);
>>>       if (!ret) {
>>>           mark_buffer_dirty(bh);
>>>           nilfs_mdt_mark_dirty(sufile);
>>> +        kaddr = kmap_atomic(bh->b_page);
>>> +        su = nilfs_sufile_block_get_segment_usage(sufile, segnum, 
>>> bh, kaddr);
>>> +        nilfs_segment_usage_set_dirty(su);
>>> +        kunmap_atomic(kaddr);
>>>           brelse(bh);
>>>       }
>>>       return ret;
>> Do we feel that this fix should be backported into -stable kernels?
> Sorry that I'm not familiar with the specific use scenarios of nilfs2. 
> So I can't offer a better advice. I think if it
> is a problem that not happen easily in normal situations there's no 
> necessary to backport it to stable.

I just noticed Ryusuke's mail so let's do it as his advice.

Thanks for your time!

Best,

Chen


  reply	other threads:[~2022-11-19  5:29 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-18  6:33 [PATCH] nilfs2: Fix nilfs_sufile_mark_dirty() not set segment usage as dirty Chen Zhongjin
2022-11-18  6:33 ` Chen Zhongjin
2022-11-18 22:11 ` Andrew Morton
2022-11-18 22:11   ` Andrew Morton
2022-11-19  4:11   ` Ryusuke Konishi
2022-11-19  4:11     ` Ryusuke Konishi
2022-11-19  5:24   ` Chen Zhongjin
2022-11-19  5:24     ` Chen Zhongjin
2022-11-19  5:28     ` Chen Zhongjin [this message]
2022-11-19  5:28       ` Chen Zhongjin
2022-11-19  7:17       ` Ryusuke Konishi
2022-11-19  7:17         ` Ryusuke Konishi
2022-11-19  7:51         ` Ryusuke Konishi
2022-11-19  7:51           ` Ryusuke Konishi
2022-11-19  9:39         ` Chen Zhongjin
2022-11-19  9:39           ` Chen Zhongjin

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=55553de4-04c3-09f3-b075-f0112d2298cb@huawei.com \
    --to=chenzhongjin@huawei.com \
    --cc=akpm@linux-foundation.org \
    --cc=konishi.ryusuke@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nilfs@vger.kernel.org \
    /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.