github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/sys/linux/fs_fuse.txt (about)

     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 fuse_unique[int64]
    10  resource fd_fuse[fd]
    11  
    12  openat$fuse(fd const[AT_FDCWD], file ptr[in, string["/dev/fuse"]], flags const[O_RDWR], mode const[0]) fd_fuse
    13  openat$cuse(fd const[AT_FDCWD], file ptr[in, string["/dev/cuse"]], flags const[O_RDWR], mode const[0]) fd_fuse
    14  ioctl$FUSE_DEV_IOC_CLONE(fd fd_fuse, cmd const[FUSE_DEV_IOC_CLONE], arg ptr[in, fd_fuse])
    15  
    16  type read_buffer array[int8, FUSE_MIN_READ_BUFFER]
    17  read$FUSE(fd fd_fuse, buf ptr[out, fuse_in[read_buffer]], len bytesize[buf])
    18  mount$fuse(src const[0], dst ptr[in, filename], type ptr[in, string["fuse"]], flags flags[mount_flags], opts ptr[in, fuse_options])
    19  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])
    20  
    21  write$FUSE_INTERRUPT(fd fd_fuse, arg ptr[in, fuse_out[void]], len bytesize[arg])
    22  write$FUSE_INIT(fd fd_fuse, arg ptr[in, fuse_out[fuse_init_out]], len bytesize[arg])
    23  write$FUSE_BMAP(fd fd_fuse, arg ptr[in, fuse_out[fuse_bmap_out]], len bytesize[arg])
    24  write$FUSE_IOCTL(fd fd_fuse, arg ptr[in, fuse_out[fuse_ioctl_out]], len bytesize[arg])
    25  write$FUSE_POLL(fd fd_fuse, arg ptr[in, fuse_out[fuse_poll_out]], len bytesize[arg])
    26  write$FUSE_LSEEK(fd fd_fuse, arg ptr[in, fuse_out[fuse_lseek_out]], len bytesize[arg])
    27  write$FUSE_LK(fd fd_fuse, arg ptr[in, fuse_out[fuse_lk_out]], len bytesize[arg])
    28  write$FUSE_GETXATTR(fd fd_fuse, arg ptr[in, fuse_out[fuse_getxattr_out]], len bytesize[arg])
    29  write$FUSE_STATFS(fd fd_fuse, arg ptr[in, fuse_out[fuse_statfs_out]], len bytesize[arg])
    30  write$FUSE_WRITE(fd fd_fuse, arg ptr[in, fuse_out[fuse_write_out]], len bytesize[arg])
    31  write$FUSE_OPEN(fd fd_fuse, arg ptr[in, fuse_out[fuse_open_out]], len bytesize[arg])
    32  write$FUSE_ATTR(fd fd_fuse, arg ptr[in, fuse_out[fuse_attr_out]], len bytesize[arg])
    33  write$FUSE_ENTRY(fd fd_fuse, arg ptr[in, fuse_out[fuse_entry_out]], len bytesize[arg])
    34  write$FUSE_CREATE_OPEN(fd fd_fuse, arg ptr[in, fuse_out[fuse_create_open_out]], len bytesize[arg])
    35  write$FUSE_DIRENT(fd fd_fuse, arg ptr[in, fuse_out[array[fuse_dirent]]], len bytesize[arg])
    36  write$FUSE_DIRENTPLUS(fd fd_fuse, arg ptr[in, fuse_out[array[fuse_direntplus]]], len bytesize[arg])
    37  write$FUSE_NOTIFY_POLL(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_POLL, fuse_notify_poll_wakeup_out]], len bytesize[arg])
    38  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])
    39  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])
    40  write$FUSE_NOTIFY_STORE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_STORE, fuse_notify_store_out]], len bytesize[arg])
    41  write$FUSE_NOTIFY_RETRIEVE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_RETRIEVE, fuse_notify_retrieve_out]], len bytesize[arg])
    42  write$FUSE_NOTIFY_DELETE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_DELETE, fuse_notify_delete_out]], len bytesize[arg])
    43  
    44  syz_mount_image$fuse(fs ptr[in, string["fuse"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fuse_options], chdir bool8, size const[0], img ptr[in, array[int8]]) fd_dir
    45  syz_fuse_handle_req(fd fd_fuse, buf ptr[in, read_buffer], len bytesize[buf], res ptr[in, syz_fuse_req_out])
    46  
    47  type fuse_ino int64[0:6]
    48  type fuse_gen int64[0:3]
    49  
    50  type fuse_notify[MSG, PAYLOAD] {
    51  	len	len[parent, int32]
    52  	err	const[MSG, int32]
    53  	unique	const[0, int64]
    54  	payload	PAYLOAD
    55  } [packed]
    56  
    57  type fuse_in[PAYLOAD] {
    58  	len	len[parent, int32]
    59  	opcode	int32
    60  	unique	fuse_unique
    61  	uid	uid
    62  	gid	gid
    63  	pid	pid
    64  	padding	int32
    65  	payload	PAYLOAD
    66  } [packed]
    67  
    68  type fuse_out_t[UNIQUE, PAYLOAD] {
    69  	len	len[parent, int32]
    70  	err	flags[fuse_errors, int32]
    71  	unique	UNIQUE
    72  	payload	PAYLOAD
    73  } [packed]
    74  
    75  type fuse_out[PAYLOAD] fuse_out_t[fuse_unique, PAYLOAD]
    76  # This response header is used by syz_fuse_handle_req(). It defines the FUSE unique
    77  # identifier as int64 because syz_fuse_handle_req() retrieves it internally
    78  # (defining it as a resource would create a dependency with read$FUSE() which is
    79  # incorrect).
    80  type syz_fuse_out[PAYLOAD] fuse_out_t[int64, PAYLOAD]
    81  
    82  # -ENOENT, -EAGAIN, -ENOSYS
    83  fuse_errors = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -11, -38
    84  
    85  fuse_init_out {
    86  	major			const[FUSE_KERNEL_VERSION, int32]
    87  	minor			const[FUSE_KERNEL_MINOR_VERSION, int32]
    88  	max_readahead		int32
    89  	flags			flags[fuse_init_flags, int32]
    90  	max_background		int16
    91  	congestion_threshold	int16
    92  	max_write		int32
    93  	time_gran		int32
    94  	max_pages		const[0, int16]
    95  	map_alignment		const[0, int16]
    96  	unused			array[const[0, int32], 8]
    97  }
    98  
    99  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, FUSE_ABORT_ERROR, FUSE_MAX_PAGES, FUSE_CACHE_SYMLINKS, FUSE_NO_OPENDIR_SUPPORT, FUSE_EXPLICIT_INVAL_DATA
   100  
   101  fuse_lseek_out {
   102  	offset	int64
   103  }
   104  
   105  fuse_bmap_out {
   106  	block	int64
   107  }
   108  
   109  fuse_ioctl_out {
   110  	res		int32
   111  	flags		flags[fuse_ioctl_flags, int32]
   112  	in_iovs		int32
   113  	out_iovs	int32
   114  }
   115  
   116  fuse_ioctl_flags = 0, FUSE_IOCTL_RETRY
   117  
   118  fuse_poll_out {
   119  	revents	int32
   120  	padding	const[0, int32]
   121  }
   122  
   123  fuse_notify_poll_wakeup_out {
   124  	kh	int64
   125  }
   126  
   127  fuse_getxattr_out {
   128  	size	int32
   129  	padding	const[0, int32]
   130  }
   131  
   132  fuse_lk_out {
   133  	lk	fuse_file_lock
   134  }
   135  
   136  fuse_file_lock {
   137  	start	int64
   138  	end	int64
   139  	type	flags[fuse_lock_type, int32]
   140  	pid	pid
   141  }
   142  
   143  fuse_lock_type = F_UNLCK, F_RDLCK, F_WRLCK
   144  
   145  fuse_statfs_out {
   146  	st	fuse_kstatfs
   147  }
   148  
   149  fuse_kstatfs {
   150  	blocks	int64
   151  	bfree	int64
   152  	bavail	int64
   153  	files	int64
   154  	ffree	int64
   155  	bsize	int32
   156  	namelen	int32
   157  	frsize	int32
   158  	padding	const[0, int32]
   159  	spare	array[const[0, int32], 6]
   160  }
   161  
   162  fuse_write_out {
   163  	size	int32
   164  	padding	const[0, int32]
   165  }
   166  
   167  fuse_read_out {
   168  	content	string
   169  }
   170  
   171  fuse_open_out {
   172  	fh		const[0, int64]
   173  	open_flags	flags[fuse_open_flags, int32]
   174  	padding		const[0, int32]
   175  }
   176  
   177  fuse_open_flags = FOPEN_DIRECT_IO, FOPEN_KEEP_CACHE, FOPEN_NONSEEKABLE, FOPEN_CACHE_DIR, FOPEN_STREAM
   178  
   179  fuse_attr_out {
   180  	attr_valid	int64
   181  	attr_valid_nsec	int32
   182  	dummy		const[0, int32]
   183  	attr		fuse_attr
   184  }
   185  
   186  fuse_entry_out {
   187  	nodeid			fuse_ino
   188  	generation		fuse_gen
   189  	entry_valid		int64
   190  	attr_valid		int64
   191  	entry_valid_nsec	int32
   192  	attr_valid_nsec		int32
   193  	attr			fuse_attr
   194  }
   195  
   196  fuse_create_open_out {
   197  	entry	fuse_entry_out
   198  	open	fuse_open_out
   199  }
   200  
   201  fuse_attr {
   202  	ino		fuse_ino
   203  	size		int64
   204  	blocks		int64
   205  	atime		int64
   206  	mtime		int64
   207  	ctime		int64
   208  	atimensec	int32
   209  	mtimensec	int32
   210  	ctimensec	int32
   211  	mode		flags[fuse_mode, int32]
   212  	nlink		int32
   213  	uid		uid
   214  	gid		gid
   215  	rdev		int32
   216  	blksize		int32
   217  	padding		const[0, int32]
   218  }
   219  
   220  fuse_dirent {
   221  	ino	fuse_ino
   222  	off	int64
   223  	namelen	len[name, int32]
   224  	type	int32
   225  	name	stringnoz
   226  } [align[8]]
   227  
   228  fuse_direntplus {
   229  	entry	fuse_entry_out
   230  	dirent	fuse_dirent
   231  }
   232  
   233  fuse_notify_inval_inode_out {
   234  	ino	fuse_ino
   235  	off	int64
   236  	len	int64
   237  }
   238  
   239  fuse_notify_inval_entry_out {
   240  	parent1	fuse_ino
   241  	namelen	len[name, int32]
   242  	padding	const[0, int32]
   243  	name	stringnoz
   244  	zero	const[0, int8]
   245  } [packed]
   246  
   247  fuse_notify_delete_out {
   248  	parent1	fuse_ino
   249  	child	fuse_ino
   250  	namelen	len[name, int32]
   251  	padding	const[0, int32]
   252  	name	stringnoz
   253  	zero	const[0, int8]
   254  } [packed]
   255  
   256  fuse_notify_store_out {
   257  	nodeid	fuse_ino
   258  	off	int64
   259  	size	len[data, int32]
   260  	padding	const[0, int32]
   261  	data	array[const[0, int8]]
   262  } [packed]
   263  
   264  fuse_notify_retrieve_out {
   265  	notify_unique	const[0, int64]
   266  	nodeid		fuse_ino
   267  	offset		int64
   268  	size		int32
   269  	padding		const[0, int32]
   270  } [packed]
   271  
   272  # Mount options.
   273  
   274  fuse_options {
   275  	fd		fs_opt_hex["fd", fd_fuse]
   276  	comma0		const[',', int8]
   277  	rootmode	fs_opt_oct["rootmode", flags[fuse_mode]]
   278  	comma1		const[',', int8]
   279  	user_id		fs_opt_dec["user_id", uid]
   280  	comma2		const[',', int8]
   281  	group_id	fs_opt_dec["group_id", gid]
   282  	comma3		const[',', int8]
   283  	opts		fs_options[fuse_opts]
   284  } [packed]
   285  
   286  fuse_opts [
   287  	max_read		fs_opt_hex["max_read", int32]
   288  	allow_other		stringnoz["allow_other"]
   289  	default_permissions	stringnoz["default_permissions"]
   290  	blksize			fs_opt_hex["blksize", flags[fuse_block_sizes]]
   291  ] [varlen]
   292  
   293  fuse_mode = S_IFREG, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK, S_IFLNK, S_IFDIR
   294  fuse_block_sizes = 512, 1024, 2048, 4096
   295  
   296  # Used by syz_fuse_handle_req() to mimic a FUSE daemon.
   297  syz_fuse_req_out {
   298  	init		ptr[in, syz_fuse_out[fuse_init_out]]
   299  	lseek		ptr[in, syz_fuse_out[fuse_lseek_out]]
   300  	bmap		ptr[in, syz_fuse_out[fuse_bmap_out]]
   301  	poll		ptr[in, syz_fuse_out[fuse_poll_out]]
   302  	getxattr	ptr[in, syz_fuse_out[fuse_getxattr_out]]
   303  	lk		ptr[in, syz_fuse_out[fuse_lk_out]]
   304  	statfs		ptr[in, syz_fuse_out[fuse_statfs_out]]
   305  	write		ptr[in, syz_fuse_out[fuse_write_out]]
   306  	read		ptr[in, syz_fuse_out[fuse_read_out]]
   307  	open		ptr[in, syz_fuse_out[fuse_open_out]]
   308  	attr		ptr[in, syz_fuse_out[fuse_attr_out]]
   309  	entry		ptr[in, syz_fuse_out[fuse_entry_out]]
   310  	dirent		ptr[in, syz_fuse_out[array[fuse_dirent]]]
   311  	direntplus	ptr[in, syz_fuse_out[array[fuse_direntplus]]]
   312  	create_open	ptr[in, syz_fuse_out[fuse_create_open_out]]
   313  	ioctl		ptr[in, syz_fuse_out[fuse_ioctl_out]]
   314  }