From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Colin Ian King <colin.king@canonical.com>
Cc: Changman Lee <cm224.lee@samsung.com>,
Chao Yu <chao2.yu@samsung.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
linux-f2fs-devel@lists.sourceforge.net
Subject: Re: [f2fs-dev] f2fs_convert_inline_inode causing rebalance based on random uninitialized value in dn.node_changed
Date: Wed, 3 Mar 2021 15:46:37 -0800 [thread overview]
Message-ID: <YEAf3W6BEUc7L3FL@google.com> (raw)
In-Reply-To: <9b586bbb-bb94-6fdf-c9a4-9415dbc6d8d0@canonical.com>
On 03/03, Colin Ian King wrote:
> On 03/03/2021 19:44, Jaegeuk Kim wrote:
> > On 03/02, Colin Ian King wrote:
> >> Hi,
> >>
> >> Static analysis on linux-next detected a potential uninitialized
> >> variable dn.node_changed that does not get set when a call to
> >> f2fs_get_node_page() fails. This uninitialized value gets used in the
> >> call to f2fs_balance_fs() that may or not may not balances dirty node
> >> and dentry pages depending on the uninitialized state of the variable.
> >>
> >> I believe the issue was introduced by commit:
> >>
> >> commit 2a3407607028f7c780f1c20faa4e922bf631d340
> >> Author: Jaegeuk Kim <jaegeuk@kernel.org>
> >> Date: Tue Dec 22 13:23:35 2015 -0800
> >>
> >> f2fs: call f2fs_balance_fs only when node was changed
> >>
> >>
> >> The analysis is a follows:
> >>
> >> 184 int f2fs_convert_inline_inode(struct inode *inode)
> >> 185 {
> >> 186 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> >>
> >> 1. var_decl: Declaring variable dn without initializer.
> >>
> >> 187 struct dnode_of_data dn;
> >>
> >> NOTE dn is not initialized here.
> >>
> >> 188 struct page *ipage, *page;
> >> 189 int err = 0;
> >> 190
> >>
> >> 2. Condition !f2fs_has_inline_data(inode), taking false branch.
> >> 3. Condition f2fs_hw_is_readonly(sbi), taking false branch.
> >> 4. Condition f2fs_readonly(sbi->sb), taking false branch.
> >>
> >> 191 if (!f2fs_has_inline_data(inode) ||
> >> 192 f2fs_hw_is_readonly(sbi) ||
> >> f2fs_readonly(sbi->sb))
> >> 193 return 0;
> >> 194
> >> 195 err = dquot_initialize(inode);
> >>
> >> 5. Condition err, taking false branch.
> >>
> >> 196 if (err)
> >> 197 return err;
> >> 198
> >> 199 page = f2fs_grab_cache_page(inode->i_mapping, 0, false);
> >>
> >> 6. Condition !page, taking false branch.
> >>
> >> 200 if (!page)
> >> 201 return -ENOMEM;
> >> 202
> >> 203 f2fs_lock_op(sbi);
> >> 204
> >> 205 ipage = f2fs_get_node_page(sbi, inode->i_ino);
> >>
> >> 7. Condition IS_ERR(ipage), taking true branch.
> >>
> >> 206 if (IS_ERR(ipage)) {
> >> 207 err = PTR_ERR(ipage);
> >>
> >> 8. Jumping to label out.
> >>
> >> 208 goto out;
> >> 209 }
> >> 210
> >>
> >> NOTE: set_new_dnode memset's dn so sets the flag to false, but we
> >> don't get to this memset if IS_ERR(ipage) above is true.
> >>
> >> 211 set_new_dnode(&dn, inode, ipage, ipage, 0);
> >> 212
> >> 213 if (f2fs_has_inline_data(inode))
> >> 214 err = f2fs_convert_inline_page(&dn, page);
> >> 215
> >> 216 f2fs_put_dnode(&dn);
> >> 217 out:
> >> 218 f2fs_unlock_op(sbi);
> >> 219
> >> 220 f2fs_put_page(page, 1);
> >> 221
> >>
> >> Uninitialized scalar variable:
> >>
> >> 9. uninit_use_in_call: Using uninitialized value dn.node_changed when
> >> calling f2fs_balance_fs.
> >>
> >> 222 f2fs_balance_fs(sbi, dn.node_changed);
> >> 223
> >> 224 return err;
> >> 225 }
> >>
> >> I think a suitable fix will be to set dn.node_changed to false on in
> >> line 207-208 but I'm concerned if I'm missing something subtle to the
> >> rebalancing if I do this.
> >>
> >> Comments?
> >
> > Thank you for the report. Yes, it seems that's a right call and we need to
> > check the error to decide calling f2fs_balance_fs() in line 222, since
> > set_new_dnode() is used to set all the fields in dnode_of_data. So, if you
> > don't mind, could you please post a patch?
>
> Just to clarify, just setting dn.node_changes to false is enough?
>
> I'm not entirely sure what you meant when you wrote "and we need to
> check the error to decide calling f2fs_balance_fs() in line 222".
I meant:
222 if (!err)
223 f2fs_balance_fs(sbi, dn.node_changed);
Thanks,
>
> Colin
>
> >
> > Thanks,
> >
> >>
> >> Colin
> >>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
WARNING: multiple messages have this Message-ID (diff)
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Colin Ian King <colin.king@canonical.com>
Cc: Changman Lee <cm224.lee@samsung.com>,
Chao Yu <chao2.yu@samsung.com>,
linux-f2fs-devel@lists.sourceforge.net,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: f2fs_convert_inline_inode causing rebalance based on random uninitialized value in dn.node_changed
Date: Wed, 3 Mar 2021 15:46:37 -0800 [thread overview]
Message-ID: <YEAf3W6BEUc7L3FL@google.com> (raw)
In-Reply-To: <9b586bbb-bb94-6fdf-c9a4-9415dbc6d8d0@canonical.com>
On 03/03, Colin Ian King wrote:
> On 03/03/2021 19:44, Jaegeuk Kim wrote:
> > On 03/02, Colin Ian King wrote:
> >> Hi,
> >>
> >> Static analysis on linux-next detected a potential uninitialized
> >> variable dn.node_changed that does not get set when a call to
> >> f2fs_get_node_page() fails. This uninitialized value gets used in the
> >> call to f2fs_balance_fs() that may or not may not balances dirty node
> >> and dentry pages depending on the uninitialized state of the variable.
> >>
> >> I believe the issue was introduced by commit:
> >>
> >> commit 2a3407607028f7c780f1c20faa4e922bf631d340
> >> Author: Jaegeuk Kim <jaegeuk@kernel.org>
> >> Date: Tue Dec 22 13:23:35 2015 -0800
> >>
> >> f2fs: call f2fs_balance_fs only when node was changed
> >>
> >>
> >> The analysis is a follows:
> >>
> >> 184 int f2fs_convert_inline_inode(struct inode *inode)
> >> 185 {
> >> 186 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> >>
> >> 1. var_decl: Declaring variable dn without initializer.
> >>
> >> 187 struct dnode_of_data dn;
> >>
> >> NOTE dn is not initialized here.
> >>
> >> 188 struct page *ipage, *page;
> >> 189 int err = 0;
> >> 190
> >>
> >> 2. Condition !f2fs_has_inline_data(inode), taking false branch.
> >> 3. Condition f2fs_hw_is_readonly(sbi), taking false branch.
> >> 4. Condition f2fs_readonly(sbi->sb), taking false branch.
> >>
> >> 191 if (!f2fs_has_inline_data(inode) ||
> >> 192 f2fs_hw_is_readonly(sbi) ||
> >> f2fs_readonly(sbi->sb))
> >> 193 return 0;
> >> 194
> >> 195 err = dquot_initialize(inode);
> >>
> >> 5. Condition err, taking false branch.
> >>
> >> 196 if (err)
> >> 197 return err;
> >> 198
> >> 199 page = f2fs_grab_cache_page(inode->i_mapping, 0, false);
> >>
> >> 6. Condition !page, taking false branch.
> >>
> >> 200 if (!page)
> >> 201 return -ENOMEM;
> >> 202
> >> 203 f2fs_lock_op(sbi);
> >> 204
> >> 205 ipage = f2fs_get_node_page(sbi, inode->i_ino);
> >>
> >> 7. Condition IS_ERR(ipage), taking true branch.
> >>
> >> 206 if (IS_ERR(ipage)) {
> >> 207 err = PTR_ERR(ipage);
> >>
> >> 8. Jumping to label out.
> >>
> >> 208 goto out;
> >> 209 }
> >> 210
> >>
> >> NOTE: set_new_dnode memset's dn so sets the flag to false, but we
> >> don't get to this memset if IS_ERR(ipage) above is true.
> >>
> >> 211 set_new_dnode(&dn, inode, ipage, ipage, 0);
> >> 212
> >> 213 if (f2fs_has_inline_data(inode))
> >> 214 err = f2fs_convert_inline_page(&dn, page);
> >> 215
> >> 216 f2fs_put_dnode(&dn);
> >> 217 out:
> >> 218 f2fs_unlock_op(sbi);
> >> 219
> >> 220 f2fs_put_page(page, 1);
> >> 221
> >>
> >> Uninitialized scalar variable:
> >>
> >> 9. uninit_use_in_call: Using uninitialized value dn.node_changed when
> >> calling f2fs_balance_fs.
> >>
> >> 222 f2fs_balance_fs(sbi, dn.node_changed);
> >> 223
> >> 224 return err;
> >> 225 }
> >>
> >> I think a suitable fix will be to set dn.node_changed to false on in
> >> line 207-208 but I'm concerned if I'm missing something subtle to the
> >> rebalancing if I do this.
> >>
> >> Comments?
> >
> > Thank you for the report. Yes, it seems that's a right call and we need to
> > check the error to decide calling f2fs_balance_fs() in line 222, since
> > set_new_dnode() is used to set all the fields in dnode_of_data. So, if you
> > don't mind, could you please post a patch?
>
> Just to clarify, just setting dn.node_changes to false is enough?
>
> I'm not entirely sure what you meant when you wrote "and we need to
> check the error to decide calling f2fs_balance_fs() in line 222".
I meant:
222 if (!err)
223 f2fs_balance_fs(sbi, dn.node_changed);
Thanks,
>
> Colin
>
> >
> > Thanks,
> >
> >>
> >> Colin
> >>
next prev parent reply other threads:[~2021-03-03 23:46 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-02 20:07 [f2fs-dev] f2fs_convert_inline_inode causing rebalance based on random uninitialized value in dn.node_changed Colin Ian King
2021-03-02 20:07 ` Colin Ian King
2021-03-03 19:44 ` [f2fs-dev] " Jaegeuk Kim
2021-03-03 19:44 ` Jaegeuk Kim
2021-03-03 22:59 ` [f2fs-dev] " Colin Ian King
2021-03-03 22:59 ` Colin Ian King
2021-03-03 23:46 ` Jaegeuk Kim [this message]
2021-03-03 23:46 ` Jaegeuk Kim
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=YEAf3W6BEUc7L3FL@google.com \
--to=jaegeuk@kernel.org \
--cc=chao2.yu@samsung.com \
--cc=cm224.lee@samsung.com \
--cc=colin.king@canonical.com \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-kernel@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.