Skip to content

Commit 9845664

Browse files
committed
btrfs: dev-replace: properly validate device names
There's a syzbot report that device name buffers passed to device replace are not properly checked for string termination which could lead to a read out of bounds in getname_kernel(). Add a helper that validates both source and target device name buffers. For devid as the source initialize the buffer to empty string in case something tries to read it later. This was originally analyzed and fixed in a different way by Edward Adam Davis (see links). Link: https://lore.kernel.org/linux-btrfs/000000000000d1a1d1060cc9c5e7@google.com/ Link: https://lore.kernel.org/linux-btrfs/tencent_44CA0665C9836EF9EEC80CB9E7E206DF5206@qq.com/ CC: stable@vger.kernel.org # 4.19+ CC: Edward Adam Davis <eadavis@qq.com> Reported-and-tested-by: syzbot+33f23b49ac24f986c9e8@syzkaller.appspotmail.com Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 5906333 commit 9845664

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

fs/btrfs/dev-replace.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,23 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
725725
return ret;
726726
}
727727

728+
static int btrfs_check_replace_dev_names(struct btrfs_ioctl_dev_replace_args *args)
729+
{
730+
if (args->start.srcdevid == 0) {
731+
if (memchr(args->start.srcdev_name, 0,
732+
sizeof(args->start.srcdev_name)) == NULL)
733+
return -ENAMETOOLONG;
734+
} else {
735+
args->start.srcdev_name[0] = 0;
736+
}
737+
738+
if (memchr(args->start.tgtdev_name, 0,
739+
sizeof(args->start.tgtdev_name)) == NULL)
740+
return -ENAMETOOLONG;
741+
742+
return 0;
743+
}
744+
728745
int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,
729746
struct btrfs_ioctl_dev_replace_args *args)
730747
{
@@ -737,10 +754,9 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,
737754
default:
738755
return -EINVAL;
739756
}
740-
741-
if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') ||
742-
args->start.tgtdev_name[0] == '\0')
743-
return -EINVAL;
757+
ret = btrfs_check_replace_dev_names(args);
758+
if (ret < 0)
759+
return ret;
744760

745761
ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,
746762
args->start.srcdevid,

0 commit comments

Comments
 (0)