1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 /* 3 * Userspace interface for Incremental FS. 4 * 5 * Incremental FS is special-purpose Linux virtual file system that allows 6 * execution of a program while its binary and resource files are still being 7 * lazily downloaded over the network, USB etc. 8 * 9 * Copyright 2019 Google LLC 10 */ 11 #ifndef _UAPI_LINUX_INCREMENTALFS_H 12 #define _UAPI_LINUX_INCREMENTALFS_H 13 14 #include <linux/limits.h> 15 #include <linux/ioctl.h> 16 #include <linux/types.h> 17 #include <linux/xattr.h> 18 19 /* ===== constants ===== */ 20 #define INCFS_NAME "incremental-fs" 21 #define INCFS_MAGIC_NUMBER (0x5346434e49ul) 22 #define INCFS_DATA_FILE_BLOCK_SIZE 4096 23 #define INCFS_HEADER_VER 1 24 25 /* TODO: This value is assumed in incfs_copy_signature_info_from_user to be the 26 * actual signature length. Set back to 64 when fixed. 27 */ 28 #define INCFS_MAX_HASH_SIZE 32 29 #define INCFS_MAX_FILE_ATTR_SIZE 512 30 31 #define INCFS_PENDING_READS_FILENAME ".pending_reads" 32 #define INCFS_LOG_FILENAME ".log" 33 #define INCFS_XATTR_ID_NAME (XATTR_USER_PREFIX "incfs.id") 34 #define INCFS_XATTR_SIZE_NAME (XATTR_USER_PREFIX "incfs.size") 35 #define INCFS_XATTR_METADATA_NAME (XATTR_USER_PREFIX "incfs.metadata") 36 37 #define INCFS_MAX_SIGNATURE_SIZE 8096 38 #define INCFS_SIGNATURE_VERSION 2 39 #define INCFS_SIGNATURE_SECTIONS 2 40 41 #define INCFS_IOCTL_BASE_CODE 'g' 42 43 /* ===== ioctl requests on the command dir ===== */ 44 45 /* Create a new file */ 46 #define INCFS_IOC_CREATE_FILE \ 47 _IOWR(INCFS_IOCTL_BASE_CODE, 30, struct incfs_new_file_args) 48 49 /* Read file signature */ 50 #define INCFS_IOC_READ_FILE_SIGNATURE \ 51 _IOR(INCFS_IOCTL_BASE_CODE, 31, struct incfs_get_file_sig_args) 52 53 /* 54 * Fill in one or more data block. This may only be called on a handle 55 * passed as a parameter to INCFS_IOC_PERMIT_FILLING 56 * 57 * Returns number of blocks filled in, or error if none were 58 */ 59 #define INCFS_IOC_FILL_BLOCKS \ 60 _IOR(INCFS_IOCTL_BASE_CODE, 32, struct incfs_fill_blocks) 61 62 /* 63 * Permit INCFS_IOC_FILL_BLOCKS on the given file descriptor 64 * May only be called on .pending_reads file 65 * 66 * Returns 0 on success or error 67 */ 68 #define INCFS_IOC_PERMIT_FILL \ 69 _IOW(INCFS_IOCTL_BASE_CODE, 33, struct incfs_permit_fill) 70 71 /* 72 * Fills buffer with ranges of populated blocks 73 * 74 * Returns 0 if all ranges written 75 * error otherwise 76 * 77 * Either way, range_buffer_size_out is set to the number 78 * of bytes written. Should be set to 0 by caller. The ranges 79 * filled are valid, but if an error was returned there might 80 * be more ranges to come. 81 * 82 * Ranges are ranges of filled blocks: 83 * 84 * 1 2 7 9 85 * 86 * means blocks 1, 2, 7, 8, 9 are filled, 0, 3, 4, 5, 6 and 10 on 87 * are not 88 * 89 * If hashing is enabled for the file, the hash blocks are simply 90 * treated as though they immediately followed the data blocks. 91 */ 92 #define INCFS_IOC_GET_FILLED_BLOCKS \ 93 _IOR(INCFS_IOCTL_BASE_CODE, 34, struct incfs_get_filled_blocks_args) 94 95 enum incfs_compression_alg { 96 COMPRESSION_NONE = 0, 97 COMPRESSION_LZ4 = 1 98 }; 99 100 enum incfs_block_flags { 101 INCFS_BLOCK_FLAGS_NONE = 0, 102 INCFS_BLOCK_FLAGS_HASH = 1, 103 }; 104 105 typedef struct { 106 __u8 bytes[16]; 107 } incfs_uuid_t __attribute__((aligned (8))); 108 109 /* 110 * Description of a pending read. A pending read - a read call by 111 * a userspace program for which the filesystem currently doesn't have data. 112 */ 113 struct incfs_pending_read_info { 114 /* Id of a file that is being read from. */ 115 incfs_uuid_t file_id; 116 117 /* A number of microseconds since system boot to the read. */ 118 __aligned_u64 timestamp_us; 119 120 /* Index of a file block that is being read. */ 121 __u32 block_index; 122 123 /* A serial number of this pending read. */ 124 __u32 serial_number; 125 }; 126 127 /* 128 * Description of a data or hash block to add to a data file. 129 */ 130 struct incfs_fill_block { 131 /* Index of a data block. */ 132 __u32 block_index; 133 134 /* Length of data */ 135 __u32 data_len; 136 137 /* 138 * A pointer to an actual data for the block. 139 * 140 * Equivalent to: __u8 *data; 141 */ 142 __aligned_u64 data; 143 144 /* 145 * Compression algorithm used to compress the data block. 146 * Values from enum incfs_compression_alg. 147 */ 148 __u8 compression; 149 150 /* Values from enum incfs_block_flags */ 151 __u8 flags; 152 153 __u16 reserved1; 154 155 __u32 reserved2; 156 157 __aligned_u64 reserved3; 158 }; 159 160 /* 161 * Description of a number of blocks to add to a data file 162 * 163 * Argument for INCFS_IOC_FILL_BLOCKS 164 */ 165 struct incfs_fill_blocks { 166 /* Number of blocks */ 167 __u64 count; 168 169 /* A pointer to an array of incfs_fill_block structs */ 170 __aligned_u64 fill_blocks; 171 }; 172 173 /* 174 * Permit INCFS_IOC_FILL_BLOCKS on the given file descriptor 175 * May only be called on .pending_reads file 176 * 177 * Argument for INCFS_IOC_PERMIT_FILL 178 */ 179 struct incfs_permit_fill { 180 /* File to permit fills on */ 181 __u32 file_descriptor; 182 }; 183 184 enum incfs_hash_tree_algorithm { 185 INCFS_HASH_TREE_NONE = 0, 186 INCFS_HASH_TREE_SHA256 = 1 187 }; 188 189 /* 190 * Create a new file or directory. 191 */ 192 struct incfs_new_file_args { 193 /* Id of a file to create. */ 194 incfs_uuid_t file_id; 195 196 /* 197 * Total size of the new file. Ignored if S_ISDIR(mode). 198 */ 199 __aligned_u64 size; 200 201 /* 202 * File mode. Permissions and dir flag. 203 */ 204 __u16 mode; 205 206 __u16 reserved1; 207 208 __u32 reserved2; 209 210 /* 211 * A pointer to a null-terminated relative path to the file's parent 212 * dir. 213 * Max length: PATH_MAX 214 * 215 * Equivalent to: char *directory_path; 216 */ 217 __aligned_u64 directory_path; 218 219 /* 220 * A pointer to a null-terminated file's name. 221 * Max length: PATH_MAX 222 * 223 * Equivalent to: char *file_name; 224 */ 225 __aligned_u64 file_name; 226 227 /* 228 * A pointer to a file attribute to be set on creation. 229 * 230 * Equivalent to: u8 *file_attr; 231 */ 232 __aligned_u64 file_attr; 233 234 /* 235 * Length of the data buffer specfied by file_attr. 236 * Max value: INCFS_MAX_FILE_ATTR_SIZE 237 */ 238 __u32 file_attr_len; 239 240 __u32 reserved4; 241 242 /* 243 * Points to an APK V4 Signature data blob 244 * Signature must have two sections 245 * Format is: 246 * u32 version 247 * u32 size_of_hash_info_section 248 * u8 hash_info_section[] 249 * u32 size_of_signing_info_section 250 * u8 signing_info_section[] 251 * 252 * Note that incfs does not care about what is in signing_info_section 253 * 254 * hash_info_section has following format: 255 * u32 hash_algorithm; // Must be SHA256 == 1 256 * u8 log2_blocksize; // Must be 12 for 4096 byte blocks 257 * u32 salt_size; 258 * u8 salt[]; 259 * u32 hash_size; 260 * u8 root_hash[]; 261 */ 262 __aligned_u64 signature_info; 263 264 /* Size of signature_info */ 265 __aligned_u64 signature_size; 266 267 __aligned_u64 reserved6; 268 }; 269 270 /* 271 * Request a digital signature blob for a given file. 272 * Argument for INCFS_IOC_READ_FILE_SIGNATURE ioctl 273 */ 274 struct incfs_get_file_sig_args { 275 /* 276 * A pointer to the data buffer to save an signature blob to. 277 * 278 * Equivalent to: u8 *file_signature; 279 */ 280 __aligned_u64 file_signature; 281 282 /* Size of the buffer at file_signature. */ 283 __u32 file_signature_buf_size; 284 285 /* 286 * Number of bytes save file_signature buffer. 287 * It is set after ioctl done. 288 */ 289 __u32 file_signature_len_out; 290 }; 291 292 struct incfs_filled_range { 293 __u32 begin; 294 __u32 end; 295 }; 296 297 /* 298 * Request ranges of filled blocks 299 * Argument for INCFS_IOC_GET_FILLED_BLOCKS 300 */ 301 struct incfs_get_filled_blocks_args { 302 /* 303 * A buffer to populate with ranges of filled blocks 304 * 305 * Equivalent to struct incfs_filled_ranges *range_buffer 306 */ 307 __aligned_u64 range_buffer; 308 309 /* Size of range_buffer */ 310 __u32 range_buffer_size; 311 312 /* Start index to read from */ 313 __u32 start_index; 314 315 /* 316 * End index to read to. 0 means read to end. This is a range, 317 * so incfs will read from start_index to end_index - 1 318 */ 319 __u32 end_index; 320 321 /* Actual number of blocks in file */ 322 __u32 total_blocks_out; 323 324 /* The number of data blocks in file */ 325 __u32 data_blocks_out; 326 327 /* Number of bytes written to range buffer */ 328 __u32 range_buffer_size_out; 329 330 /* Sector scanned up to, if the call was interrupted */ 331 __u32 index_out; 332 }; 333 334 #endif /* _UAPI_LINUX_INCREMENTALFS_H */ 335