# Copyright 2020 syzkaller project authors. All rights reserved. # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. include include include include include include include include ioctl$BTRFS_IOC_SNAP_CREATE(fd fd, cmd const[BTRFS_IOC_SNAP_CREATE], arg ptr[in, btrfs_ioctl_vol_args]) ioctl$BTRFS_IOC_SNAP_CREATE_V2(fd fd, cmd const[BTRFS_IOC_SNAP_CREATE_V2], arg ptr[in, btrfs_ioctl_vol_args_v2]) ioctl$BTRFS_IOC_SUBVOL_CREATE(fd fd, cmd const[BTRFS_IOC_SUBVOL_CREATE], arg ptr[in, btrfs_ioctl_vol_args]) ioctl$BTRFS_IOC_SUBVOL_CREATE_V2(fd fd, cmd const[BTRFS_IOC_SUBVOL_CREATE_V2], arg ptr[in, btrfs_ioctl_vol_args_v2]) ioctl$BTRFS_IOC_SNAP_DESTROY(fd fd, cmd const[BTRFS_IOC_SNAP_DESTROY], arg ptr[in, btrfs_ioctl_vol_args]) ioctl$BTRFS_IOC_SNAP_DESTROY_V2(fd fd, cmd const[BTRFS_IOC_SNAP_DESTROY_V2], arg ptr[in, btrfs_ioctl_vol_args_v2]) ioctl$BTRFS_IOC_SUBVOL_GETFLAGS(fd fd, cmd const[BTRFS_IOC_SUBVOL_GETFLAGS], arg ptr[out, int64]) ioctl$BTRFS_IOC_SUBVOL_SETFLAGS(fd fd, cmd const[BTRFS_IOC_SUBVOL_SETFLAGS], arg ptr[in, flags[btrfs_subvol_flags, int64]]) ioctl$BTRFS_IOC_DEFAULT_SUBVOL(fd fd, cmd const[BTRFS_IOC_DEFAULT_SUBVOL], arg ptr[in, subvolid]) ioctl$BTRFS_IOC_DEFRAG(fd fd, cmd const[BTRFS_IOC_DEFRAG], arg const[0]) ioctl$BTRFS_IOC_DEFRAG_RANGE(fd fd, cmd const[BTRFS_IOC_DEFRAG_RANGE], arg ptr[in, btrfs_ioctl_defrag_range_args, opt]) ioctl$BTRFS_IOC_RESIZE(fd fd, cmd const[BTRFS_IOC_RESIZE], arg ptr[in, btrfs_ioctl_resize_args]) ioctl$BTRFS_IOC_ADD_DEV(fd fd, cmd const[BTRFS_IOC_ADD_DEV], arg ptr[in, btrfs_ioctl_vol_args]) ioctl$BTRFS_IOC_RM_DEV(fd fd, cmd const[BTRFS_IOC_RM_DEV], arg ptr[in, btrfs_ioctl_vol_args]) ioctl$BTRFS_IOC_RM_DEV_V2(fd fd, cmd const[BTRFS_IOC_RM_DEV_V2], arg ptr[in, btrfs_ioctl_vol_args_v2]) ioctl$BTRFS_IOC_FS_INFO(fd fd, cmd const[BTRFS_IOC_FS_INFO], arg ptr[out, btrfs_ioctl_fs_info_args]) ioctl$BTRFS_IOC_DEV_INFO(fd fd, cmd const[BTRFS_IOC_DEV_INFO], arg ptr[inout, btrfs_ioctl_dev_info_args]) ioctl$BTRFS_IOC_BALANCE(fd fd, cmd const[BTRFS_IOC_BALANCE], arg const[0]) ioctl$BTRFS_IOC_TREE_SEARCH(fd fd, cmd const[BTRFS_IOC_TREE_SEARCH], arg ptr[inout, btrfs_ioctl_search_args]) ioctl$BTRFS_IOC_TREE_SEARCH_V2(fd fd, cmd const[BTRFS_IOC_TREE_SEARCH_V2], arg ptr[inout, btrfs_ioctl_search_args_v2]) ioctl$BTRFS_IOC_INO_LOOKUP(fd fd, cmd const[BTRFS_IOC_INO_LOOKUP], arg ptr[in, btrfs_ioctl_ino_lookup_args]) ioctl$BTRFS_IOC_INO_PATHS(fd fd, cmd const[BTRFS_IOC_INO_PATHS], arg ptr[inout, btrfs_ioctl_ino_path_args]) ioctl$BTRFS_IOC_LOGICAL_INO(fd fd, cmd const[BTRFS_IOC_LOGICAL_INO], arg ptr[inout, btrfs_ioctl_logical_ino_args]) ioctl$BTRFS_IOC_LOGICAL_INO_V2(fd fd, cmd const[BTRFS_IOC_LOGICAL_INO_V2], arg ptr[inout, btrfs_ioctl_logical_ino_args]) ioctl$BTRFS_IOC_SPACE_INFO(fd fd, cmd const[BTRFS_IOC_SPACE_INFO], arg ptr[inout, btrfs_ioctl_space_args]) ioctl$BTRFS_IOC_SYNC(fd fd, cmd const[BTRFS_IOC_SYNC], arg const[0]) ioctl$BTRFS_IOC_START_SYNC(fd fd, cmd const[BTRFS_IOC_START_SYNC], arg ptr[out, transid]) ioctl$BTRFS_IOC_WAIT_SYNC(fd fd, cmd const[BTRFS_IOC_WAIT_SYNC], arg ptr[in, transid, opt]) ioctl$BTRFS_IOC_SCRUB(fd fd, cmd const[BTRFS_IOC_SCRUB], arg ptr[inout, btrfs_ioctl_scrub_args]) ioctl$BTRFS_IOC_SCRUB_CANCEL(fd fd, cmd const[BTRFS_IOC_SCRUB_CANCEL], arg const[0]) ioctl$BTRFS_IOC_SCRUB_PROGRESS(fd fd, cmd const[BTRFS_IOC_SCRUB_PROGRESS], arg ptr[inout, btrfs_ioctl_scrub_args]) ioctl$BTRFS_IOC_BALANCE_V2(fd fd, cmd const[BTRFS_IOC_BALANCE_V2], arg ptr[inout, btrfs_ioctl_balance_args]) ioctl$BTRFS_IOC_BALANCE_CTL(fd fd, cmd const[BTRFS_IOC_BALANCE_CTL], arg flags[btrfs_balance_ctl_values]) ioctl$BTRFS_IOC_BALANCE_PROGRESS(fd fd, cmd const[BTRFS_IOC_BALANCE_PROGRESS], arg ptr[out, btrfs_ioctl_balance_args]) ioctl$BTRFS_IOC_SET_RECEIVED_SUBVOL(fd fd, cmd const[BTRFS_IOC_SET_RECEIVED_SUBVOL], arg ptr[inout, btrfs_ioctl_received_subvol_args]) ioctl$BTRFS_IOC_SEND(fd fd, cmd const[BTRFS_IOC_SEND], arg ptr[in, btrfs_ioctl_send_args]) ioctl$BTRFS_IOC_GET_DEV_STATS(fd fd, cmd const[BTRFS_IOC_GET_DEV_STATS], arg ptr[inout, btrfs_ioctl_get_dev_stats]) ioctl$BTRFS_IOC_QUOTA_CTL(fd fd, cmd const[BTRFS_IOC_QUOTA_CTL], arg ptr[in, btrfs_ioctl_quota_ctl_args]) ioctl$BTRFS_IOC_QGROUP_ASSIGN(fd fd, cmd const[BTRFS_IOC_QGROUP_ASSIGN], arg ptr[in, btrfs_ioctl_qgroup_assign_args]) ioctl$BTRFS_IOC_QGROUP_CREATE(fd fd, cmd const[BTRFS_IOC_QGROUP_CREATE], arg ptr[in, btrfs_ioctl_qgroup_create_args]) ioctl$BTRFS_IOC_QGROUP_LIMIT(fd fd, cmd const[BTRFS_IOC_QGROUP_LIMIT], arg ptr[in, btrfs_ioctl_qgroup_limit_args]) ioctl$BTRFS_IOC_QUOTA_RESCAN(fd fd, cmd const[BTRFS_IOC_QUOTA_RESCAN], arg ptr[in, btrfs_ioctl_quota_rescan_args]) ioctl$BTRFS_IOC_QUOTA_RESCAN_STATUS(fd fd, cmd const[BTRFS_IOC_QUOTA_RESCAN_STATUS], arg ptr[out, btrfs_ioctl_quota_rescan_args]) ioctl$BTRFS_IOC_QUOTA_RESCAN_WAIT(fd fd, cmd const[BTRFS_IOC_QUOTA_RESCAN_WAIT], arg const[0]) ioctl$BTRFS_IOC_DEV_REPLACE(fd fd, cmd const[BTRFS_IOC_DEV_REPLACE], arg ptr[inout, btrfs_ioctl_dev_replace_args]) ioctl$BTRFS_IOC_GET_SUPPORTED_FEATURES(fd fd, cmd const[BTRFS_IOC_GET_SUPPORTED_FEATURES], arg ptr[out, array[btrfs_ioctl_feature_flags, 3]]) ioctl$BTRFS_IOC_GET_FEATURES(fd fd, cmd const[BTRFS_IOC_GET_FEATURES], arg ptr[out, btrfs_ioctl_feature_flags]) ioctl$BTRFS_IOC_SET_FEATURES(fd fd, cmd const[BTRFS_IOC_SET_FEATURES], arg ptr[in, btrfs_ioctl_feature_flags]) ioctl$BTRFS_IOC_GET_SUBVOL_INFO(fd fd, cmd const[BTRFS_IOC_GET_SUBVOL_INFO], arg ptr[out, btrfs_ioctl_get_subvol_info_args]) ioctl$BTRFS_IOC_GET_SUBVOL_ROOTREF(fd fd, cmd const[BTRFS_IOC_GET_SUBVOL_ROOTREF], arg ptr[inout, btrfs_ioctl_get_subvol_rootref_args]) ioctl$BTRFS_IOC_INO_LOOKUP_USER(fd fd, cmd const[BTRFS_IOC_INO_LOOKUP_USER], arg ptr[inout, btrfs_ioctl_ino_lookup_user_args]) resource transid[int64] resource devid[int64] resource treeid[int64] resource dirid[int64] # These should be a resource but it's not returned by any syscall. So we temporarily describe them as type type qgroupid int64 type objectid int64 type subvolid objectid #NEED: uuid should be a resource define BTRFS_PATH_MAX BTRFS_PATH_NAME_MAX+1 define BTRFS_SUBVOL_MAX BTRFS_SUBVOL_NAME_MAX+1 #The following two struct needs to be customized to fit the need of each specific ioctls calling them #But I still need more information in order to make the change btrfs_ioctl_vol_args { fd align64[fd] name array[int8, BTRFS_PATH_MAX] } btrfs_ioctl_vol_args_v2 { fd align64[fd] transid transid flags flags[btrfs_ioctl_vol_args_v2_flags, int64] u1 btrfs_vol_args_v2_u1 u2 btrfs_vol_args_v2_u2 } btrfs_vol_args_v2_u1 [ inherit btrfs_vol_args_v2_u1_s1 unused array[int64, 4] ] btrfs_vol_args_v2_u2 [ name array[int8, BTRFS_SUBVOL_MAX] devid devid subvolid subvolid ] btrfs_vol_args_v2_u1_s1 { size bytesize[qgroup_inherit, int64] qgroup_inherit ptr[in, btrfs_qgroup_inherit] } btrfs_qgroup_inherit { flags flags[btrfs_qgroup_inherit_flags, int64] num_qgroups len[qgroups, int64] num_ref_copies int64 num_excl_copies int64 lim btrfs_qgroup_limit qgroups array[qgroupid] } btrfs_qgroup_limit { flags flags[btrfs_qgroup_limit_flags, int64] max_rfer int64 max_excl int64 rsv_rfer int64 rsv_excl int64 } btrfs_ioctl_defrag_range_args { start int64 len int64 flags flags[btrfs_ioctl_defrag_range_args_flags, int64] extent_thresh int32 compress_type flags[btrfs_compression_type, int32] unused array[int32, 4] } btrfs_ioctl_fs_info_args { max_id const[0, int64] num_devices const[0, int64] fsid array[const[0, int8], BTRFS_FSID_SIZE] nodesize const[0, int32] sectorize const[0, int32] clone_alignment const[0, int32] reserved32 const[0, int32] reserved array[const[0, int64], 122] } btrfs_ioctl_dev_info_args { devid devid uuid array[int8, BTRFS_UUID_SIZE] bytes_used const[0, int64] total_bytes const[0, int64] unused array[const[0, int64], 379] path array[const[0, int8], BTRFS_DEVICE_PATH_NAME_MAX] } btrfs_ioctl_search_args { key btrfs_ioctl_search_key buf array[const[0, int8], BTRFS_SEARCH_ARGS_BUFSIZE] } btrfs_ioctl_search_key { tree_id treeid min_objectid int64 max_objectid int64 min_offset int64 max_offset int64 min_transid int64 max_transid int64 min_type int32 max_type int32 nr_items int32 unused int32 unused1 int64 unused2 int64 unused3 int64 unused4 int64 } btrfs_ioctl_search_args_v2 { key btrfs_ioctl_search_key buf_size bytesize[buf, int64] buf array[const[0, int64]] } btrfs_ioctl_ino_lookup_args { treeid treeid objectid objectid name array[const[0, int8], BTRFS_INO_LOOKUP_PATH_MAX] } btrfs_ioctl_ino_path_args { inum int64 size bytesize[fspath, int64] reserved array[int64, 4] fspath ptr64[out, array[const[0, int64]]] } btrfs_ioctl_logical_ino_args { logical int64 size bytesize[inodes, int64] reserved array[const[0, int64], 3] flags flags[btrfs_ioctl_logical_ino_args_flags, int64] inodes ptr64[out, array[const[0, int64]]] } btrfs_ioctl_space_args { space_slots len[spaces, int64] total_spaces int64 spaces array[array[const[0, int64], 3], 0:4096] } # btrfs_scrub_progress is ignored since that will only be used for out btrfs_ioctl_scrub_args { devid devid start int64 end int64 flags flags[btrfs_ioctl_scrub_args_flags, int64] unused array[const[0, int64], 124] } btrfs_ioctl_balance_args { flags flags[btrfs_ioctl_balance_args_flags, int64] state flags[btrfs_ioctl_balance_args_states, int64] data btrfs_balance_args meta btrfs_balance_args sys btrfs_balance_args stat btrfs_balance_progress unused array[const[0, int64], 72] } btrfs_balance_args_u [ usage int64 struct btrfs_balance_args_u_s1 ] btrfs_balance_args_u_s1 { usage_min int32 usage_max int32 } btrfs_balance_args { profiles int64 union1 btrfs_balance_args_u devid devid pstart int64 pend int64 vstart int64 vend int64 target int64 flags flags[btrfs_balance_args_flags, int64] union2 btrfs_balance_args_u stripes_min int32 stripes_max int32 unused array[int64, 6] } [packed] btrfs_balance_progress { expected int64 considered int64 completed int64 } btrfs_ioctl_received_subvol_args { uuid array[int8, BTRFS_UUID_SIZE] stransid transid rtransid transid stime btrfs_ioctl_timespec rtime btrfs_ioctl_timespec flags int64 reserved array[int64, 16] } btrfs_ioctl_timespec { sec int64 msec int32 } btrfs_ioctl_send_args { send_fd padto64[fd] clone_sources_count len[clone_sources, int64] clone_sources ptr[in, array[subvolid]] parent_root int64 flags flags[btrfs_ioctl_send_flags, int64] version int32[0:1] reserved array[const[0, int8], 28] } #This pads the struct to 1032 bytes. It was originally meant to pad to #1024 bytes, but when adding the flags field, the padding calculation #was not adjusted. define BTRFS_DEV_PAD 128-2-BTRFS_DEV_STAT_VALUES_MAX btrfs_ioctl_get_dev_stats { devid devid nr_items int64 flags flags[btrfs_ioctl_get_dev_stats_flags, int64] values array[int64, BTRFS_DEV_STAT_VALUES_MAX] unused array[int64, BTRFS_DEV_PAD] } btrfs_ioctl_quota_ctl_args { cmd flags[btrfs_ioctl_quota_ctl_cmd, int64] status int64 } btrfs_ioctl_qgroup_assign_args { assign bool64 src qgroupid dst qgroupid } btrfs_ioctl_qgroup_create_args { create bool64 qgroupid qgroupid } btrfs_ioctl_qgroup_limit_args { qgroupid qgroupid lim btrfs_qgroup_limit } btrfs_ioctl_quota_rescan_args { flags const[0, int64] progress int64 reserved array[int64, 6] } btrfs_ioctl_dev_replace_args_u [ start btrfs_ioctl_dev_replace_start_params status btrfs_ioctl_dev_replace_status_params ] btrfs_ioctl_dev_replace_args { cmd flags[btrfs_ioctl_dev_replace_args_cmd, int64] result int64 union1 btrfs_ioctl_dev_replace_args_u spare array[int64, 64] } define BTRFS_DEVICE_MAX BTRFS_DEVICE_PATH_NAME_MAX + 1 btrfs_ioctl_dev_replace_start_params { srcdevid devid cont_reading_from_srcdev_mode flags[cont_reading_from_srcdev_mode_flags, int64] srcdev_name array[int8, BTRFS_DEVICE_MAX] tgtdev_name array[int8, BTRFS_DEVICE_MAX] } #this structure is just for out, hence no need to describe btrfs_ioctl_dev_replace_status_params { dummys array[int64, 6] } btrfs_ioctl_feature_flags { compat_flags flags[btrfs_ioctl_feature_compat_flags, int64] compat_ro_flags flags[btrfs_ioctl_feature_compat_ro_flags, int64] incompat_flags flags[btrfs_ioctl_feature_incompat_flags, int64] } define BTRFS_VOL_MAX BTRFS_VOL_NAME_MAX+1 #described since the uuid, transid and treeid is going to be useful as resource btrfs_ioctl_get_subvol_info_args { treeid treeid name array[int8, BTRFS_VOL_MAX] parent_id treeid dirid dirid generation transid flags int64 uuid array[int8, BTRFS_UUID_SIZE] parent_uuid array[int8, BTRFS_UUID_SIZE] received_uuid array[int8, BTRFS_UUID_SIZE] ctransid transid otransid transid stransid transid rtransid transid ctime btrfs_ioctl_timespec otime btrfs_ioctl_timespec stime btrfs_ioctl_timespec rtime btrfs_ioctl_timespec reserved array[const[0, int64], 8] } btrfs_ioctl_get_subvol_rootref_args { min_treeid int64 rootref array[btrfs_ioctl_get_subvol_rootref_args_s1, BTRFS_MAX_ROOTREF_BUFFER_NUM] num_items int8 align array[int8, 7] } btrfs_ioctl_get_subvol_rootref_args_s1 { treeid treeid dirid dirid } btrfs_ioctl_ino_lookup_user_args { dirid dirid treeid treeid name array[int8, BTRFS_VOL_MAX] path array[int8, BTRFS_INO_LOOKUP_USER_PATH_MAX] } btrfs_ioctl_resize_args { fd align64[fd] name btrfs_ioctl_resize_string } btrfs_ioctl_resize_string { devid optional[btrfs_devid_colon] resize_num btrfs_ioctl_resize_size } [packed] btrfs_devid_colon { devid fmt[dec, devid] colon const[':', int8] } btrfs_ioctl_resize_size [ actul_num btrfs_ioctl_resize_size_num max stringnoz["max"] ] [varlen] btrfs_ioctl_resize_size_num { plus_minus optional[flags[plus_minus, int8]] num fmt[dec, int32] kKmM flags[all_these_kKmM, int8] } [packed] plus_minus = '+', '-' all_these_kKmM = 'k', 'K', 'm', 'M', 'g', 'G', 't', 'T', 'p', 'P', 'e', 'E' btrfs_ioctl_vol_args_v2_flags = BTRFS_SUBVOL_RDONLY, BTRFS_SUBVOL_QGROUP_INHERIT, BTRFS_DEVICE_SPEC_BY_ID, BTRFS_SUBVOL_SPEC_BY_ID btrfs_qgroup_inherit_flags = BTRFS_QGROUP_INHERIT_SET_LIMITS btrfs_qgroup_limit_flags = BTRFS_QGROUP_LIMIT_MAX_RFER, BTRFS_QGROUP_LIMIT_MAX_EXCL, BTRFS_QGROUP_LIMIT_RSV_RFER, BTRFS_QGROUP_LIMIT_RSV_EXCL, BTRFS_QGROUP_LIMIT_RFER_CMPR, BTRFS_QGROUP_LIMIT_EXCL_CMPR btrfs_subvol_flags = BTRFS_SUBVOL_RDONLY btrfs_ioctl_defrag_range_args_flags = BTRFS_DEFRAG_RANGE_COMPRESS, BTRFS_DEFRAG_RANGE_START_IO btrfs_compression_type = BTRFS_COMPRESS_NONE, BTRFS_COMPRESS_ZLIB, BTRFS_COMPRESS_LZO, BTRFS_COMPRESS_ZSTD btrfs_ioctl_logical_ino_args_flags = BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET btrfs_ioctl_scrub_args_flags = BTRFS_SCRUB_READONLY btrfs_balance_ctl_values = BTRFS_BALANCE_CTL_PAUSE, BTRFS_BALANCE_CTL_CANCEL btrfs_balance_args_flags = BTRFS_BALANCE_ARGS_PROFILES, BTRFS_BALANCE_ARGS_USAGE, BTRFS_BALANCE_ARGS_DEVID, BTRFS_BALANCE_ARGS_DRANGE, BTRFS_BALANCE_ARGS_VRANGE, BTRFS_BALANCE_ARGS_LIMIT, BTRFS_BALANCE_ARGS_LIMIT_RANGE, BTRFS_BALANCE_ARGS_STRIPES_RANGE, BTRFS_BALANCE_ARGS_USAGE_RANGE btrfs_ioctl_balance_args_states = BTRFS_BALANCE_STATE_RUNNING, BTRFS_BALANCE_STATE_PAUSE_REQ, BTRFS_BALANCE_STATE_CANCEL_REQ btrfs_ioctl_balance_args_flags = BTRFS_BALANCE_DATA, BTRFS_BALANCE_SYSTEM, BTRFS_BALANCE_METADATA, BTRFS_BALANCE_FORCE, BTRFS_BALANCE_RESUME btrfs_ioctl_send_flags = BTRFS_SEND_FLAG_NO_FILE_DATA, BTRFS_SEND_FLAG_OMIT_STREAM_HEADER, BTRFS_SEND_FLAG_OMIT_END_CMD, BTRFS_SEND_FLAG_VERSION btrfs_ioctl_get_dev_stats_flags = BTRFS_DEV_STATS_RESET btrfs_ioctl_quota_ctl_cmd = BTRFS_QUOTA_CTL_ENABLE, BTRFS_QUOTA_CTL_DISABLE, BTRFS_QUOTA_CTL_RESCAN__NOTUSED btrfs_ioctl_dev_replace_args_cmd = BTRFS_IOCTL_DEV_REPLACE_CMD_START, BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS, BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL, BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR, BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED, BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED, BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS cont_reading_from_srcdev_mode_flags = BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS, BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID btrfs_ioctl_feature_compat_flags = btrfs_ioctl_feature_compat_ro_flags btrfs_ioctl_feature_compat_ro_flags = BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE, BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID btrfs_ioctl_feature_incompat_flags = BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF, BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL, BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS, BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO, BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD