public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: gniebler@suse.com
Cc: linux-btrfs@vger.kernel.org
Subject: [bug report] btrfs: turn fs_roots_radix in btrfs_fs_info into an XArray
Date: Wed, 4 May 2022 18:29:18 +0300	[thread overview]
Message-ID: <YnKbzreg3dLw9QTa@kili> (raw)

Hello Gabriel Niebler,

The patch eb8da5bf4831: "btrfs: turn fs_roots_radix in btrfs_fs_info
into an XArray" from Apr 26, 2022, leads to the following Smatch
static checker warning:

fs/btrfs/disk-io.c:4453 btrfs_cleanup_fs_roots() error: uninitialized symbol 'i'.
fs/btrfs/disk-io.c:4453 btrfs_cleanup_fs_roots() error: uninitialized symbol 'grabbed'.

fs/btrfs/disk-io.c
    4408 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
    4409 {
    4410         struct btrfs_root *roots[8];
    4411         unsigned long index = 0;
    4412         int i;
    4413         int err = 0;
    4414         int grabbed;
    4415 
    4416         while (1) {
    4417                 struct btrfs_root *root;
    4418 
    4419                 spin_lock(&fs_info->fs_roots_lock);
    4420                 if (!xa_find(&fs_info->fs_roots, &index, ULONG_MAX, XA_PRESENT)) {
    4421                         spin_unlock(&fs_info->fs_roots_lock);
    4422                         break;

"i" and "grabbed" are uninitialized if we hit this break statement on
the first iteration through the loop.

roots is also uninitialized.  This error handling is badly broken.

If we hit it on the second iteration then we are also toasted.  Double
frees.  I think.  (Trying to send emails quickly and then head out the
door).

    4423                 }
    4424 
    4425                 grabbed = 0;
    4426                 xa_for_each_start(&fs_info->fs_roots, index, root, index) {
    4427                         /* Avoid grabbing roots in dead_roots */
    4428                         if (btrfs_root_refs(&root->root_item) == 0) {
    4429                                 roots[grabbed] = NULL;
    4430                         } else {
    4431                                 /* Grab all the search results for later use */
    4432                                 roots[grabbed] = btrfs_grab_root(root);
    4433                         }
    4434                         grabbed++;
    4435                         if (grabbed >= ARRAY_SIZE(roots))
    4436                                 break;
    4437                 }
    4438                 spin_unlock(&fs_info->fs_roots_lock);
    4439 
    4440                 for (i = 0; i < grabbed; i++) {
    4441                         if (!roots[i])
    4442                                 continue;
    4443                         index = roots[i]->root_key.objectid;
    4444                         err = btrfs_orphan_cleanup(roots[i]);
    4445                         if (err)
    4446                                 break;

Imagine we hit this break.  Double frees as well.

    4447                         btrfs_put_root(roots[i]);
    4448                 }
    4449                 index++;
    4450         }
    4451 
    4452         /* Release the roots that remain uncleaned due to error */
--> 4453         for (; i < grabbed; i++) {
                        ^^^^^^^^^^^

    4454                 if (roots[i])
    4455                         btrfs_put_root(roots[i]);
    4456         }
    4457         return err;
    4458 }

regards,
dan carpenter

             reply	other threads:[~2022-05-04 15:29 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-04 15:29 Dan Carpenter [this message]
2022-05-11 13:10 ` [bug report] btrfs: turn fs_roots_radix in btrfs_fs_info into an XArray David Sterba
  -- strict thread matches above, loose matches on Subject: below --
2022-05-16  8:04 Dan Carpenter
2022-05-16 10:39 ` Nikolay Borisov
2022-05-16 11:02   ` Dan Carpenter
2022-05-16 11:45     ` Nikolay Borisov
2022-05-16 15:18       ` David Sterba

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=YnKbzreg3dLw9QTa@kili \
    --to=dan.carpenter@oracle.com \
    --cc=gniebler@suse.com \
    --cc=linux-btrfs@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox