Skip to content

Commit fd4e994

Browse files
osandovkdave
authored andcommitted
Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2()
If we have invalid flags set, when we error out we must drop our writer counter and free the buffer we allocated for the arguments. This bug is trivially reproduced with the following program on 4.7+: #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <linux/btrfs.h> #include <linux/btrfs_tree.h> int main(int argc, char **argv) { struct btrfs_ioctl_vol_args_v2 vol_args = { .flags = UINT64_MAX, }; int ret; int fd; if (argc != 2) { fprintf(stderr, "usage: %s PATH\n", argv[0]); return EXIT_FAILURE; } fd = open(argv[1], O_WRONLY); if (fd == -1) { perror("open"); return EXIT_FAILURE; } ret = ioctl(fd, BTRFS_IOC_RM_DEV_V2, &vol_args); if (ret == -1) perror("ioctl"); close(fd); return EXIT_SUCCESS; } When unmounting the filesystem, we'll hit the WARN_ON(mnt_get_writers(mnt)) in cleanup_mnt() and also may prevent the filesystem to be remounted read-only as the writer count will stay lifted. Fixes: 6b526ed ("btrfs: introduce device delete by devid") CC: [email protected] # 4.9+ Signed-off-by: Omar Sandoval <[email protected]> Reviewed-by: Su Yue <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent de885e3 commit fd4e994

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

fs/btrfs/ioctl.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,8 +2613,10 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
26132613
}
26142614

26152615
/* Check for compatibility reject unknown flags */
2616-
if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED)
2617-
return -EOPNOTSUPP;
2616+
if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED) {
2617+
ret = -EOPNOTSUPP;
2618+
goto out;
2619+
}
26182620

26192621
if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
26202622
ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;

0 commit comments

Comments
 (0)