Unverified Commit f6ff720f authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11573 btrfs: fix a use-after-free when hitting errors inside btrfs_submit_chunk()

parents c146a1f1 fc41e282
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -646,7 +646,6 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
{
	struct btrfs_inode *inode = bbio->inode;
	struct btrfs_fs_info *fs_info = bbio->fs_info;
	struct btrfs_bio *orig_bbio = bbio;
	struct bio *bio = &bbio->bio;
	u64 logical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
	u64 length = bio->bi_iter.bi_size;
@@ -682,7 +681,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
		bbio->saved_iter = bio->bi_iter;
		ret = btrfs_lookup_bio_sums(bbio);
		if (ret)
			goto fail_put_bio;
			goto fail;
	}

	if (btrfs_op(bio) == BTRFS_MAP_WRITE) {
@@ -704,13 +703,13 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)

			ret = btrfs_bio_csum(bbio);
			if (ret)
				goto fail_put_bio;
				goto fail;
		} else if (use_append ||
			   (btrfs_is_zoned(fs_info) && inode &&
			    inode->flags & BTRFS_INODE_NODATASUM)) {
			ret = btrfs_alloc_dummy_sum(bbio);
			if (ret)
				goto fail_put_bio;
				goto fail;
		}
	}

@@ -718,12 +717,23 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
done:
	return map_length == length;

fail_put_bio:
	if (map_length < length)
		btrfs_cleanup_bio(bbio);
fail:
	btrfs_bio_counter_dec(fs_info);
	btrfs_bio_end_io(orig_bbio, ret);
	/*
	 * We have split the original bbio, now we have to end both the current
	 * @bbio and remaining one, as the remaining one will never be submitted.
	 */
	if (map_length < length) {
		struct btrfs_bio *remaining = bbio->private;

		ASSERT(bbio->bio.bi_pool == &btrfs_clone_bioset);
		ASSERT(remaining);

		remaining->bio.bi_status = ret;
		btrfs_orig_bbio_end_io(remaining);
	}
	bbio->bio.bi_status = ret;
	btrfs_orig_bbio_end_io(bbio);
	/* Do not submit another chunk */
	return true;
}