github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/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  ioctl$FUSE_DEV_IOC_BACKING_OPEN(fd fd_fuse, cmd const[FUSE_DEV_IOC_BACKING_OPEN], arg ptr[in, fuse_backing_map])
    16  ioctl$FUSE_DEV_IOC_BACKING_CLOSE(fd fd_fuse, cmd const[FUSE_DEV_IOC_BACKING_CLOSE], arg ptr[in, int32])
    17  
    18  type read_buffer array[int8, FUSE_MIN_READ_BUFFER]
    19  read$FUSE(fd fd_fuse, buf ptr[out, fuse_in[read_buffer]], len bytesize[buf])
    20  mount$fuse(src const[0], dst ptr[in, filename], type ptr[in, string["fuse"]], flags flags[mount_flags], opts ptr[in, fuse_options])
    21  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])
    22  
    23  write$FUSE_INTERRUPT(fd fd_fuse, arg ptr[in, fuse_out[void]], len bytesize[arg])
    24  write$FUSE_INIT(fd fd_fuse, arg ptr[in, fuse_out[fuse_init_out]], len bytesize[arg])
    25  write$FUSE_BMAP(fd fd_fuse, arg ptr[in, fuse_out[fuse_bmap_out]], len bytesize[arg])
    26  write$FUSE_IOCTL(fd fd_fuse, arg ptr[in, fuse_out[fuse_ioctl_out]], len bytesize[arg])
    27  write$FUSE_POLL(fd fd_fuse, arg ptr[in, fuse_out[fuse_poll_out]], len bytesize[arg])
    28  write$FUSE_LSEEK(fd fd_fuse, arg ptr[in, fuse_out[fuse_lseek_out]], len bytesize[arg])
    29  write$FUSE_LK(fd fd_fuse, arg ptr[in, fuse_out[fuse_lk_out]], len bytesize[arg])
    30  write$FUSE_GETXATTR(fd fd_fuse, arg ptr[in, fuse_out[fuse_getxattr_out]], len bytesize[arg])
    31  write$FUSE_STATFS(fd fd_fuse, arg ptr[in, fuse_out[fuse_statfs_out]], len bytesize[arg])
    32  write$FUSE_WRITE(fd fd_fuse, arg ptr[in, fuse_out[fuse_write_out]], len bytesize[arg])
    33  write$FUSE_OPEN(fd fd_fuse, arg ptr[in, fuse_out[fuse_open_out]], len bytesize[arg])
    34  write$FUSE_ATTR(fd fd_fuse, arg ptr[in, fuse_out[fuse_attr_out]], len bytesize[arg])
    35  write$FUSE_ENTRY(fd fd_fuse, arg ptr[in, fuse_out[fuse_entry_out]], len bytesize[arg])
    36  write$FUSE_CREATE_OPEN(fd fd_fuse, arg ptr[in, fuse_out[fuse_create_open_out]], len bytesize[arg])
    37  write$FUSE_DIRENT(fd fd_fuse, arg ptr[in, fuse_out[array[fuse_dirent]]], len bytesize[arg])
    38  write$FUSE_DIRENTPLUS(fd fd_fuse, arg ptr[in, fuse_out[array[fuse_direntplus]]], len bytesize[arg])
    39  write$FUSE_STATX(fd fd_fuse, arg ptr[in, fuse_out[fuse_statx_out]], len bytesize[arg])
    40  write$FUSE_NOTIFY_POLL(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_POLL, fuse_notify_poll_wakeup_out]], len bytesize[arg])
    41  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])
    42  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])
    43  write$FUSE_NOTIFY_STORE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_STORE, fuse_notify_store_out]], len bytesize[arg])
    44  write$FUSE_NOTIFY_RETRIEVE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_RETRIEVE, fuse_notify_retrieve_out]], len bytesize[arg])
    45  write$FUSE_NOTIFY_DELETE(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_DELETE, fuse_notify_delete_out]], len bytesize[arg])
    46  write$FUSE_NOTIFY_RESEND(fd fd_fuse, arg ptr[in, fuse_notify[FUSE_NOTIFY_RESEND, const[0, int32]]], len bytesize[arg])
    47  
    48  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
    49  syz_fuse_handle_req(fd fd_fuse, buf ptr[in, read_buffer], len bytesize[buf], res ptr[in, syz_fuse_req_out])
    50  
    51  type fuse_ino int64[0:6]
    52  type fuse_gen int64[0:3]
    53  
    54  type fuse_notify[MSG, PAYLOAD] {
    55  	len	len[parent, int32]
    56  	err	const[MSG, int32]
    57  	unique	const[0, int64]
    58  	payload	PAYLOAD
    59  } [packed]
    60  
    61  type fuse_in[PAYLOAD] {
    62  	len	len[parent, int32]
    63  	opcode	int32
    64  	unique	fuse_unique
    65  	uid	uid
    66  	gid	gid
    67  	pid	pid
    68  	padding	int32
    69  	payload	PAYLOAD
    70  } [packed]
    71  
    72  type fuse_out_t[UNIQUE, PAYLOAD] {
    73  	len	len[parent, int32]
    74  	err	flags[fuse_errors, int32]
    75  	unique	UNIQUE
    76  	payload	PAYLOAD
    77  } [packed]
    78  
    79  type fuse_out[PAYLOAD] fuse_out_t[fuse_unique, PAYLOAD]
    80  # This response header is used by syz_fuse_handle_req(). It defines the FUSE unique
    81  # identifier as int64 because syz_fuse_handle_req() retrieves it internally
    82  # (defining it as a resource would create a dependency with read$FUSE() which is
    83  # incorrect).
    84  type syz_fuse_out[PAYLOAD] fuse_out_t[int64, PAYLOAD]
    85  
    86  # -ENOENT, -EAGAIN, -ENOSYS
    87  fuse_errors = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -11, -38
    88  
    89  fuse_init_out {
    90  	major			const[FUSE_KERNEL_VERSION, int32]
    91  	minor			const[FUSE_KERNEL_MINOR_VERSION, int32]
    92  	max_readahead		int32
    93  	flags			flags[fuse_init_flags, int32]
    94  	max_background		int16
    95  	congestion_threshold	int16
    96  	max_write		int32
    97  	time_gran		int32
    98  	max_pages		const[0, int16]
    99  	map_alignment		const[0, int16]
   100  	flags2			flags[fuse_init_flags2, int32]
   101  	max_stack_depth		int32
   102  	unused			array[const[0, int32], 6]
   103  }
   104  
   105  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, FUSE_MAP_ALIGNMENT, FUSE_SUBMOUNTS, FUSE_HANDLE_KILLPRIV_V2, FUSE_SETXATTR_EXT, FUSE_INIT_EXT, FUSE_INIT_RESERVED
   106  fuse_init_flags2 = FUSE_SECURITY_CTX_FLAG2, FUSE_HAS_INODE_DAX_FLAG2, FUSE_CREATE_SUPP_GROUP_FLAG2, FUSE_HAS_EXPIRE_ONLY_FLAG2, FUSE_DIRECT_IO_ALLOW_MMAP_FLAG2, FUSE_PASSTHROUGH_FLAG2, FUSE_NO_EXPORT_SUPPORT_FLAG2, FUSE_HAS_RESEND_FLAG2, FUSE_DIRECT_IO_RELAX_FLAG2, FUSE_ALLOW_IDMAP_FLAG2
   107  
   108  define FUSE_SECURITY_CTX_FLAG2	FUSE_SECURITY_CTX >> 32
   109  define FUSE_HAS_INODE_DAX_FLAG2	FUSE_HAS_INODE_DAX >> 32
   110  define FUSE_CREATE_SUPP_GROUP_FLAG2	FUSE_CREATE_SUPP_GROUP >> 32
   111  define FUSE_HAS_EXPIRE_ONLY_FLAG2	FUSE_HAS_EXPIRE_ONLY >> 32
   112  define FUSE_DIRECT_IO_ALLOW_MMAP_FLAG2	FUSE_DIRECT_IO_ALLOW_MMAP >> 32
   113  define FUSE_PASSTHROUGH_FLAG2	FUSE_PASSTHROUGH >> 32
   114  define FUSE_NO_EXPORT_SUPPORT_FLAG2	FUSE_NO_EXPORT_SUPPORT >> 32
   115  define FUSE_HAS_RESEND_FLAG2	FUSE_HAS_RESEND >> 32
   116  define FUSE_DIRECT_IO_RELAX_FLAG2	FUSE_DIRECT_IO_RELAX >> 32
   117  define FUSE_ALLOW_IDMAP_FLAG2	FUSE_ALLOW_IDMAP >> 32 
   118  
   119  fuse_lseek_out {
   120  	offset	int64
   121  }
   122  
   123  fuse_bmap_out {
   124  	block	int64
   125  }
   126  
   127  fuse_ioctl_out {
   128  	res		int32
   129  	flags		flags[fuse_ioctl_flags, int32]
   130  	in_iovs		int32
   131  	out_iovs	int32
   132  }
   133  
   134  fuse_ioctl_flags = 0, FUSE_IOCTL_RETRY
   135  
   136  fuse_poll_out {
   137  	revents	int32
   138  	padding	const[0, int32]
   139  }
   140  
   141  fuse_notify_poll_wakeup_out {
   142  	kh	int64
   143  }
   144  
   145  fuse_getxattr_out {
   146  	size	int32
   147  	padding	const[0, int32]
   148  }
   149  
   150  fuse_lk_out {
   151  	lk	fuse_file_lock
   152  }
   153  
   154  fuse_file_lock {
   155  	start	int64
   156  	end	int64
   157  	type	flags[fuse_lock_type, int32]
   158  	pid	pid
   159  }
   160  
   161  fuse_lock_type = F_UNLCK, F_RDLCK, F_WRLCK
   162  
   163  fuse_statfs_out {
   164  	st	fuse_kstatfs
   165  }
   166  
   167  fuse_kstatfs {
   168  	blocks	int64
   169  	bfree	int64
   170  	bavail	int64
   171  	files	int64
   172  	ffree	int64
   173  	bsize	int32
   174  	namelen	int32
   175  	frsize	int32
   176  	padding	const[0, int32]
   177  	spare	array[const[0, int32], 6]
   178  }
   179  
   180  fuse_write_out {
   181  	size	int32
   182  	padding	const[0, int32]
   183  }
   184  
   185  fuse_read_out {
   186  	content	string
   187  }
   188  
   189  fuse_open_out {
   190  	fh		const[0, int64]
   191  	open_flags	flags[fuse_open_flags, int32]
   192  	padding		const[0, int32]
   193  }
   194  
   195  fuse_open_flags = FOPEN_DIRECT_IO, FOPEN_KEEP_CACHE, FOPEN_NONSEEKABLE, FOPEN_CACHE_DIR, FOPEN_STREAM
   196  
   197  fuse_attr_out {
   198  	attr_valid	int64
   199  	attr_valid_nsec	int32
   200  	dummy		const[0, int32]
   201  	attr		fuse_attr
   202  }
   203  
   204  fuse_entry_out {
   205  	nodeid			fuse_ino
   206  	generation		fuse_gen
   207  	entry_valid		int64
   208  	attr_valid		int64
   209  	entry_valid_nsec	int32
   210  	attr_valid_nsec		int32
   211  	attr			fuse_attr
   212  }
   213  
   214  fuse_create_open_out {
   215  	entry	fuse_entry_out
   216  	open	fuse_open_out
   217  }
   218  
   219  fuse_attr {
   220  	ino		fuse_ino
   221  	size		int64
   222  	blocks		int64
   223  	atime		int64
   224  	mtime		int64
   225  	ctime		int64
   226  	atimensec	int32
   227  	mtimensec	int32
   228  	ctimensec	int32
   229  	mode		flags[fuse_mode, int32]
   230  	nlink		int32
   231  	uid		uid
   232  	gid		gid
   233  	rdev		int32
   234  	blksize		int32
   235  	padding		const[0, int32]
   236  }
   237  
   238  fuse_dirent {
   239  	ino	fuse_ino
   240  	off	int64
   241  	namelen	len[name, int32]
   242  	type	int32
   243  	name	stringnoz
   244  } [align[8]]
   245  
   246  fuse_direntplus {
   247  	entry	fuse_entry_out
   248  	dirent	fuse_dirent
   249  }
   250  
   251  fuse_notify_inval_inode_out {
   252  	ino	fuse_ino
   253  	off	int64
   254  	len	int64
   255  }
   256  
   257  fuse_notify_inval_entry_out {
   258  	parent1	fuse_ino
   259  	namelen	len[name, int32]
   260  	padding	const[0, int32]
   261  	name	stringnoz
   262  	zero	const[0, int8]
   263  } [packed]
   264  
   265  fuse_notify_delete_out {
   266  	parent1	fuse_ino
   267  	child	fuse_ino
   268  	namelen	len[name, int32]
   269  	padding	const[0, int32]
   270  	name	stringnoz
   271  	zero	const[0, int8]
   272  } [packed]
   273  
   274  fuse_notify_store_out {
   275  	nodeid	fuse_ino
   276  	off	int64
   277  	size	len[data, int32]
   278  	padding	const[0, int32]
   279  	data	array[const[0, int8]]
   280  } [packed]
   281  
   282  fuse_notify_retrieve_out {
   283  	notify_unique	const[0, int64]
   284  	nodeid		fuse_ino
   285  	offset		int64
   286  	size		int32
   287  	padding		const[0, int32]
   288  } [packed]
   289  
   290  fuse_statx_out {
   291  	attr_valid	int64
   292  	attr_valid_nsec	int32
   293  	flags		const[0, int32]
   294  	spare		array[const[0, int64], 2]
   295  	stat		fuse_statx
   296  }
   297  
   298  fuse_statx {
   299  	mask		flags[fuse_statx_masx, int32]
   300  	blksize		int32
   301  	attributes	int64
   302  	nlink		int32
   303  	uid		uid
   304  	gid		gid
   305  	mode		flags[fuse_valid_type, int16]
   306  	__spare0	array[const[0, int16], 1]
   307  	ino		int64
   308  	size		int64
   309  	blocks		int64
   310  	attributes_mask	int64
   311  	atime		fuse_sx_time
   312  	btime		fuse_sx_time
   313  	ctime		fuse_sx_time
   314  	mtime		fuse_sx_time
   315  	rdev_major	int32
   316  	rdev_minor	int32
   317  	dev_major	int32
   318  	dev_minor	int32
   319  	__spare2	array[const[0, int64], 14]
   320  }
   321  
   322  fuse_statx_masx = STATX_TYPE, STATX_MODE, STATX_NLINK, STATX_UID, STATX_GID, STATX_ATIME, STATX_MTIME, STATX_CTIME, STATX_INO, STATX_SIZE, STATX_BLOCKS, STATX_BASIC_STATS, STATX_BTIME, STATX_MNT_ID, STATX_DIOALIGN, STATX_MNT_ID_UNIQUE, STATX_SUBVOL, STATX_WRITE_ATOMIC
   323  
   324  fuse_valid_type = S_IFLNK, S_IFREG, S_IFDIR, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK
   325  
   326  fuse_sx_time {
   327  	tv_sec		int64
   328  	tv_nsec		int32
   329  	__reserved	const[0, int32]
   330  }
   331  
   332  # Mount options.
   333  
   334  fuse_options {
   335  	fd		fs_opt_hex["fd", fd_fuse]
   336  	comma0		const[',', int8]
   337  	rootmode	fs_opt_oct["rootmode", flags[fuse_mode]]
   338  	comma1		const[',', int8]
   339  	user_id		fs_opt_dec["user_id", uid]
   340  	comma2		const[',', int8]
   341  	group_id	fs_opt_dec["group_id", gid]
   342  	comma3		const[',', int8]
   343  	opts		fs_options[fuse_opts]
   344  } [packed]
   345  
   346  fuse_opts [
   347  	max_read		fs_opt_hex["max_read", int32]
   348  	allow_other		stringnoz["allow_other"]
   349  	default_permissions	stringnoz["default_permissions"]
   350  	blksize			fs_opt_hex["blksize", flags[fuse_block_sizes]]
   351  ] [varlen]
   352  
   353  fuse_mode = S_IFREG, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK, S_IFLNK, S_IFDIR
   354  fuse_block_sizes = 512, 1024, 2048, 4096
   355  
   356  # Used by syz_fuse_handle_req() to mimic a FUSE daemon.
   357  syz_fuse_req_out {
   358  	init		ptr[in, syz_fuse_out[fuse_init_out]]
   359  	lseek		ptr[in, syz_fuse_out[fuse_lseek_out]]
   360  	bmap		ptr[in, syz_fuse_out[fuse_bmap_out]]
   361  	poll		ptr[in, syz_fuse_out[fuse_poll_out]]
   362  	getxattr	ptr[in, syz_fuse_out[fuse_getxattr_out]]
   363  	lk		ptr[in, syz_fuse_out[fuse_lk_out]]
   364  	statfs		ptr[in, syz_fuse_out[fuse_statfs_out]]
   365  	write		ptr[in, syz_fuse_out[fuse_write_out]]
   366  	read		ptr[in, syz_fuse_out[fuse_read_out]]
   367  	open		ptr[in, syz_fuse_out[fuse_open_out]]
   368  	attr		ptr[in, syz_fuse_out[fuse_attr_out]]
   369  	entry		ptr[in, syz_fuse_out[fuse_entry_out]]
   370  	dirent		ptr[in, syz_fuse_out[array[fuse_dirent]]]
   371  	direntplus	ptr[in, syz_fuse_out[array[fuse_direntplus]]]
   372  	create_open	ptr[in, syz_fuse_out[fuse_create_open_out]]
   373  	ioctl		ptr[in, syz_fuse_out[fuse_ioctl_out]]
   374  	statx		ptr[in, syz_fuse_out[fuse_statx_out]]
   375  }
   376  
   377  fuse_backing_map {
   378  	fd	fd_fuse
   379  	flags	const[0, int32]
   380  	padding	const[0, int64]
   381  }