1 # Copyright 2015 syzkaller project authors. All rights reserved. 2 # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 include <asm/ioctls.h> 5 include <linux/stat.h> 6 include <uapi/linux/fuse.h> 7 include <uapi/linux/fcntl.h> 8 9 resource fd_fuse[fd] 10 11 openat$fuse(fd const[AT_FDCWD], file ptr[in, string["/dev/fuse"]], flags const[O_RDWR], mode const[0]) fd_fuse 12 ioctl$FUSE_DEV_IOC_CLONE(fd fd_fuse, cmd const[FUSE_DEV_IOC_CLONE], arg ptr[in, fd_fuse]) 13 read$FUSE(fd fd_fuse, buf ptr[out, array[int8, 4096]], len len[buf]) 14 15 mount$fuse(src const[0], dst ptr[in, filename], type ptr[in, string["fuse"]], flags flags[mount_flags], opts ptr[in, fuse_options]) 16 mount$fuseblk(src ptr[in, string["/dev/loop0"]], dst ptr[in, filename], type ptr[in, string["fuseblk"]], flags flags[mount_flags], opts ptr[in, fuse_options]) 17 18 write$FUSE_INTERRUPT(fd fd_fuse, arg ptr[in, fuse_out[void]], len bytesize[arg]) 19 write$FUSE_INIT(fd fd_fuse, arg ptr[in, fuse_out[fuse_init_out]], len bytesize[arg]) 20 write$FUSE_BMAP(fd fd_fuse, arg ptr[in, fuse_out[fuse_bmap_out]], len bytesize[arg]) 21 write$FUSE_IOCTL(fd fd_fuse, arg ptr[in, fuse_out[fuse_ioctl_out]], len bytesize[arg]) 22 write$FUSE_POLL(fd fd_fuse, arg ptr[in, fuse_out[fuse_poll_out]], len bytesize[arg]) 23 write$FUSE_LSEEK(fd fd_fuse, arg ptr[in, fuse_out[fuse_lseek_out]], len bytesize[arg]) 24 write$FUSE_LK(fd fd_fuse, arg ptr[in, fuse_out[fuse_lk_out]], len bytesize[arg]) 25 write$FUSE_GETXATTR(fd fd_fuse, arg ptr[in, fuse_out[fuse_getxattr_out]], len bytesize[arg]) 26 write$FUSE_STATFS(fd fd_fuse, arg ptr[in, fuse_out[fuse_statfs_out]], len bytesize[arg]) 27 write$FUSE_WRITE(fd fd_fuse, arg ptr[in, fuse_out[fuse_write_out]], len bytesize[arg]) 28 write$FUSE_OPEN(fd fd_fuse, arg ptr[in, fuse_out[fuse_open_out]], len bytesize[arg]) 29 write$FUSE_ATTR(fd fd_fuse, arg ptr[in, fuse_out[fuse_attr_out]], len bytesize[arg]) 30 write$FUSE_ENTRY(fd fd_fuse, arg ptr[in, fuse_out[fuse_entry_out]], len bytesize[arg]) 31 write$FUSE_CREATE_OPEN(fd fd_fuse, arg ptr[in, fuse_out[fuse_create_open_out]], len bytesize[arg]) 32 write$FUSE_DIRENT(fd fd_fuse, arg ptr[in, fuse_out[array[fuse_dirent]]], len bytesize[arg]) 33 write$FUSE_DIRENTPLUS(fd fd_fuse, arg ptr[in, fuse_out[array[fuse_direntplus]]], len bytesize[arg]) 34 write$FUSE_NOTIFY_POLL(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_POLL, fuse_notify_poll_wakeup_out]], len bytesize[arg]) 35 write$FUSE_NOTIFY_INVAL_INODE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_INVAL_INODE, fuse_notify_inval_inode_out]], len bytesize[arg]) 36 write$FUSE_NOTIFY_INVAL_ENTRY(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_INVAL_ENTRY, fuse_notify_inval_entry_out]], len bytesize[arg]) 37 write$FUSE_NOTIFY_STORE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_STORE, fuse_notify_store_out]], len bytesize[arg]) 38 write$FUSE_NOTIFY_RETRIEVE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_RETRIEVE, fuse_notify_retrieve_out]], len bytesize[arg]) 39 write$FUSE_NOTIFY_DELETE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_DELETE, fuse_notify_delete_out]], len bytesize[arg]) 40 41 type fuse_ino int64[0:6] 42 type fuse_gen int64[0:3] 43 type fuse_unique int64[1:8] 44 45 type fuse_notify[MSG, PAYLOAD] { 46 len len[parent, int32] 47 err const[MSG, int32] 48 unique const[0, int64] 49 payload PAYLOAD 50 } [packed] 51 52 type fuse_out[PAYLOAD] { 53 len len[parent, int32] 54 err flags[fuse_errors, int32] 55 unique fuse_unique 56 payload PAYLOAD 57 } [packed] 58 59 # -ENOENT, -EAGAIN, -ENOSYS 60 fuse_errors = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -11, -38 61 62 fuse_init_out { 63 maj const[FUSE_KERNEL_VERSION, int32] 64 min const[FUSE_KERNEL_MINOR_VERSION, int32] 65 max_readahead int32 66 flags flags[fuse_init_flags, int32] 67 max_background int16 68 congestion_threshold int16 69 max_write int32 70 time_gran int32 71 unused array[const[0, int32], 9] 72 } 73 74 fuse_init_flags = FUSE_ASYNC_READ, FUSE_POSIX_LOCKS, FUSE_FILE_OPS, FUSE_ATOMIC_O_TRUNC, FUSE_EXPORT_SUPPORT, FUSE_BIG_WRITES, FUSE_DONT_MASK, FUSE_SPLICE_WRITE, FUSE_SPLICE_MOVE, FUSE_SPLICE_READ, FUSE_FLOCK_LOCKS, FUSE_HAS_IOCTL_DIR, FUSE_AUTO_INVAL_DATA, FUSE_DO_READDIRPLUS, FUSE_READDIRPLUS_AUTO, FUSE_ASYNC_DIO, FUSE_WRITEBACK_CACHE, FUSE_NO_OPEN_SUPPORT, FUSE_PARALLEL_DIROPS, FUSE_HANDLE_KILLPRIV, FUSE_POSIX_ACL 75 76 fuse_lseek_out { 77 offset int64 78 } 79 80 fuse_bmap_out { 81 block int64 82 } 83 84 fuse_ioctl_out { 85 res int32 86 flags flags[fuse_ioctl_flags, int32] 87 in_iovs int32 88 out_iovs int32 89 } 90 91 fuse_ioctl_flags = 0, FUSE_IOCTL_RETRY 92 93 fuse_poll_out { 94 revents int32 95 padding const[0, int32] 96 } 97 98 fuse_notify_poll_wakeup_out { 99 kh int64 100 } 101 102 fuse_getxattr_out { 103 size int32 104 padding const[0, int32] 105 } 106 107 fuse_lk_out { 108 lk fuse_file_lock 109 } 110 111 fuse_file_lock { 112 start int64 113 end int64 114 type flags[fuse_lock_type, int32] 115 pid pid 116 } 117 118 fuse_lock_type = F_UNLCK, F_RDLCK, F_WRLCK 119 120 fuse_statfs_out { 121 st fuse_kstatfs 122 } 123 124 fuse_kstatfs { 125 blocks int64 126 bfree int64 127 bavail int64 128 files int64 129 ffree int64 130 bsize int32 131 namelen int32 132 frsize int32 133 padding_spare array[const[0, int32], 7] 134 } 135 136 fuse_write_out { 137 size int32 138 padding const[0, int32] 139 } 140 141 fuse_open_out { 142 fh const[0, int64] 143 open_flags flags[fuse_open_flags, int32] 144 padding const[0, int32] 145 } 146 147 fuse_open_flags = FOPEN_DIRECT_IO, FOPEN_KEEP_CACHE, FOPEN_NONSEEKABLE 148 149 fuse_attr_out { 150 attr_valid int64 151 attr_valid_nsec int32 152 dummy const[0, int32] 153 attr fuse_attr 154 } 155 156 fuse_entry_out { 157 nodeid fuse_ino 158 generation fuse_gen 159 entry_valid int64 160 attr_valid int64 161 entry_valid_nsec int32 162 attr_valid_nsec int32 163 attr fuse_attr 164 } 165 166 fuse_create_open_out { 167 entry fuse_entry_out 168 open fuse_open_out 169 } 170 171 fuse_attr { 172 ino fuse_ino 173 size int64 174 blocks int64 175 atime int64 176 mtime int64 177 ctime int64 178 atimensec int32 179 mtimensec int32 180 ctimensec int32 181 mode int32 182 nlink int32 183 uid uid 184 gid gid 185 rdev int32 186 blksize int32 187 padding const[0, int32] 188 } 189 190 fuse_dirent { 191 ino fuse_ino 192 off int64 193 namelen len[name, int32] 194 type int32 195 name stringnoz 196 } [align_8] 197 198 fuse_direntplus { 199 entry fuse_entry_out 200 dirent fuse_dirent 201 } 202 203 fuse_notify_inval_inode_out { 204 ino fuse_ino 205 off int64 206 len int64 207 } 208 209 fuse_notify_inval_entry_out { 210 parent1 fuse_ino 211 namelen len[name, int32] 212 padding const[0, int32] 213 name stringnoz 214 zero const[0, int8] 215 } [packed] 216 217 fuse_notify_delete_out { 218 parent1 fuse_ino 219 child fuse_ino 220 namelen len[name, int32] 221 padding const[0, int32] 222 name stringnoz 223 zero const[0, int8] 224 } [packed] 225 226 fuse_notify_store_out { 227 nodeid fuse_ino 228 off int64 229 size len[data, int32] 230 padding const[0, int32] 231 data array[const[0, int8]] 232 } [packed] 233 234 fuse_notify_retrieve_out { 235 notify_unique const[0, int64] 236 nodeid fuse_ino 237 offset int64 238 size int32 239 padding const[0, int32] 240 } [packed] 241 242 # Mount options. 243 244 fuse_options { 245 fd fs_opt_hex["fd", fd_fuse] 246 comma0 const[',', int8] 247 rootmode fs_opt_oct["rootmode", flags[fuse_mode]] 248 comma1 const[',', int8] 249 user_id fs_opt_dec["user_id", uid] 250 comma2 const[',', int8] 251 group_id fs_opt_dec["group_id", gid] 252 comma3 const[',', int8] 253 opts fs_options[fuse_opts] 254 } [packed] 255 256 fuse_opts [ 257 max_read fs_opt_hex["max_read", int32] 258 allow_other stringnoz["allow_other"] 259 default_permissions stringnoz["default_permissions"] 260 blksize fs_opt_hex["blksize", flags[fuse_block_sizes]] 261 ] [varlen] 262 263 fuse_mode = S_IFREG, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK, S_IFLNK, S_IFDIR 264 fuse_block_sizes = 512, 1024, 2048, 4096 265