1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Filesystem access-by-fd. 3 * 4 * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/fs_context.h> 9 #include <linux/fs_parser.h> 10 #include <linux/slab.h> 11 #include <linux/uaccess.h> 12 #include <linux/syscalls.h> 13 #include <linux/security.h> 14 #include <linux/anon_inodes.h> 15 #include <linux/namei.h> 16 #include <linux/file.h> 17 #include <uapi/linux/mount.h> 18 #include <linux/audit.h> 19 #include "internal.h" 20 #include "mount.h" 21 22 static inline const char *fetch_message_locked(struct fc_log *log, size_t len, 23 bool *need_free) 24 { 25 const char *p; 26 int index; 27 28 if (unlikely(log->head == log->tail)) 29 return ERR_PTR(-ENODATA); 30 31 index = log->tail & (ARRAY_SIZE(log->buffer) - 1); 32 p = log->buffer[index]; 33 if (unlikely(strlen(p) > len)) 34 return ERR_PTR(-EMSGSIZE); 35 36 log->buffer[index] = NULL; 37 *need_free = log->need_free & (1 << index); 38 log->need_free &= ~(1 << index); 39 log->tail++; 40 41 return p; 42 } 43 44 /* 45 * Allow the user to read back any error, warning or informational messages. 46 * Only one message is returned for each read(2) call. 47 */ 48 static ssize_t fscontext_read(struct file *file, 49 char __user *_buf, size_t len, loff_t *pos) 50 { 51 struct fs_context *fc = file->private_data; 52 ssize_t err; 53 const char *p __free(kfree) = NULL, *message; 54 bool need_free; 55 int n; 56 57 err = mutex_lock_interruptible(&fc->uapi_mutex); 58 if (err < 0) 59 return err; 60 message = fetch_message_locked(fc->log.log, len, &need_free); 61 mutex_unlock(&fc->uapi_mutex); 62 if (IS_ERR(message)) 63 return PTR_ERR(message); 64 65 if (need_free) 66 p = message; 67 68 n = strlen(message); 69 if (copy_to_user(_buf, message, n)) 70 return -EFAULT; 71 return n; 72 } 73 74 static int fscontext_release(struct inode *inode, struct file *file) 75 { 76 struct fs_context *fc = file->private_data; 77 78 if (fc) { 79 file->private_data = NULL; 80 put_fs_context(fc); 81 } 82 return 0; 83 } 84 85 const struct file_operations fscontext_fops = { 86 .read = fscontext_read, 87 .release = fscontext_release, 88 }; 89 90 /* 91 * Attach a filesystem context to a file and an fd. 92 */ 93 static int fscontext_create_fd(struct fs_context *fc, unsigned int o_flags) 94 { 95 int fd; 96 97 fd = anon_inode_getfd("[fscontext]", &fscontext_fops, fc, 98 O_RDWR | o_flags); 99 if (fd < 0) 100 put_fs_context(fc); 101 return fd; 102 } 103 104 static int fscontext_alloc_log(struct fs_context *fc) 105 { 106 fc->log.log = kzalloc_obj(*fc->log.log); 107 if (!fc->log.log) 108 return -ENOMEM; 109 refcount_set(&fc->log.log->usage, 1); 110 fc->log.log->owner = fc->fs_type->owner; 111 return 0; 112 } 113 114 /* 115 * Open a filesystem by name so that it can be configured for mounting. 116 * 117 * We are allowed to specify a container in which the filesystem will be 118 * opened, thereby indicating which namespaces will be used (notably, which 119 * network namespace will be used for network filesystems). 120 */ 121 SYSCALL_DEFINE2(fsopen, const char __user *, _fs_name, unsigned int, flags) 122 { 123 struct file_system_type *fs_type; 124 struct fs_context *fc; 125 const char *fs_name; 126 int ret; 127 128 if (!may_mount()) 129 return -EPERM; 130 131 if (flags & ~FSOPEN_CLOEXEC) 132 return -EINVAL; 133 134 fs_name = strndup_user(_fs_name, PAGE_SIZE); 135 if (IS_ERR(fs_name)) 136 return PTR_ERR(fs_name); 137 138 audit_log_fsopen(fs_name); 139 140 fs_type = get_fs_type(fs_name); 141 kfree(fs_name); 142 if (!fs_type) 143 return -ENODEV; 144 145 fc = fs_context_for_mount(fs_type, 0); 146 put_filesystem(fs_type); 147 if (IS_ERR(fc)) 148 return PTR_ERR(fc); 149 150 fc->phase = FS_CONTEXT_CREATE_PARAMS; 151 152 ret = fscontext_alloc_log(fc); 153 if (ret < 0) 154 goto err_fc; 155 156 return fscontext_create_fd(fc, flags & FSOPEN_CLOEXEC ? O_CLOEXEC : 0); 157 158 err_fc: 159 put_fs_context(fc); 160 return ret; 161 } 162 163 /* 164 * Pick a superblock into a context for reconfiguration. 165 */ 166 SYSCALL_DEFINE3(fspick, int, dfd, const char __user *, path, unsigned int, flags) 167 { 168 struct fs_context *fc; 169 struct path target; 170 unsigned int lookup_flags; 171 int ret; 172 173 if (!may_mount()) 174 return -EPERM; 175 176 if ((flags & ~(FSPICK_CLOEXEC | 177 FSPICK_SYMLINK_NOFOLLOW | 178 FSPICK_NO_AUTOMOUNT | 179 FSPICK_EMPTY_PATH)) != 0) 180 return -EINVAL; 181 182 lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT; 183 if (flags & FSPICK_SYMLINK_NOFOLLOW) 184 lookup_flags &= ~LOOKUP_FOLLOW; 185 if (flags & FSPICK_NO_AUTOMOUNT) 186 lookup_flags &= ~LOOKUP_AUTOMOUNT; 187 CLASS(filename_flags, filename)(path, 188 (flags & FSPICK_EMPTY_PATH) ? LOOKUP_EMPTY : 0); 189 ret = filename_lookup(dfd, filename, lookup_flags, &target, NULL); 190 if (ret < 0) 191 goto err; 192 193 ret = -EINVAL; 194 if (target.mnt->mnt_root != target.dentry) 195 goto err_path; 196 197 fc = fs_context_for_reconfigure(target.dentry, 0, 0); 198 if (IS_ERR(fc)) { 199 ret = PTR_ERR(fc); 200 goto err_path; 201 } 202 203 fc->phase = FS_CONTEXT_RECONF_PARAMS; 204 205 ret = fscontext_alloc_log(fc); 206 if (ret < 0) 207 goto err_fc; 208 209 path_put(&target); 210 return fscontext_create_fd(fc, flags & FSPICK_CLOEXEC ? O_CLOEXEC : 0); 211 212 err_fc: 213 put_fs_context(fc); 214 err_path: 215 path_put(&target); 216 err: 217 return ret; 218 } 219 220 static int vfs_cmd_create(struct fs_context *fc, bool exclusive) 221 { 222 struct super_block *sb; 223 int ret; 224 225 if (fc->phase != FS_CONTEXT_CREATE_PARAMS) 226 return -EBUSY; 227 228 if (!mount_capable(fc)) 229 return -EPERM; 230 231 fc->phase = FS_CONTEXT_CREATING; 232 fc->exclusive = exclusive; 233 234 ret = vfs_get_tree(fc); 235 if (ret) { 236 fc->phase = FS_CONTEXT_FAILED; 237 return ret; 238 } 239 240 sb = fc->root->d_sb; 241 ret = security_sb_kern_mount(sb); 242 if (unlikely(ret)) { 243 fc_drop_locked(fc); 244 fc->phase = FS_CONTEXT_FAILED; 245 return ret; 246 } 247 248 /* vfs_get_tree() callchains will have grabbed @s_umount */ 249 up_write(&sb->s_umount); 250 fc->phase = FS_CONTEXT_AWAITING_MOUNT; 251 return 0; 252 } 253 254 static int vfs_cmd_reconfigure(struct fs_context *fc) 255 { 256 struct super_block *sb; 257 int ret; 258 259 if (fc->phase != FS_CONTEXT_RECONF_PARAMS) 260 return -EBUSY; 261 262 fc->phase = FS_CONTEXT_RECONFIGURING; 263 264 sb = fc->root->d_sb; 265 if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) { 266 fc->phase = FS_CONTEXT_FAILED; 267 return -EPERM; 268 } 269 270 down_write(&sb->s_umount); 271 ret = reconfigure_super(fc); 272 up_write(&sb->s_umount); 273 if (ret) { 274 fc->phase = FS_CONTEXT_FAILED; 275 return ret; 276 } 277 278 vfs_clean_context(fc); 279 return 0; 280 } 281 282 /* 283 * Check the state and apply the configuration. Note that this function is 284 * allowed to 'steal' the value by setting param->xxx to NULL before returning. 285 */ 286 static int vfs_fsconfig_locked(struct fs_context *fc, int cmd, 287 struct fs_parameter *param) 288 { 289 int ret; 290 291 ret = finish_clean_context(fc); 292 if (ret) 293 return ret; 294 switch (cmd) { 295 case FSCONFIG_CMD_CREATE: 296 return vfs_cmd_create(fc, false); 297 case FSCONFIG_CMD_CREATE_EXCL: 298 return vfs_cmd_create(fc, true); 299 case FSCONFIG_CMD_RECONFIGURE: 300 return vfs_cmd_reconfigure(fc); 301 default: 302 if (fc->phase != FS_CONTEXT_CREATE_PARAMS && 303 fc->phase != FS_CONTEXT_RECONF_PARAMS) 304 return -EBUSY; 305 306 return vfs_parse_fs_param(fc, param); 307 } 308 } 309 310 /** 311 * sys_fsconfig - Set parameters and trigger actions on a context 312 * @fd: The filesystem context to act upon 313 * @cmd: The action to take 314 * @_key: Where appropriate, the parameter key to set 315 * @_value: Where appropriate, the parameter value to set 316 * @aux: Additional information for the value 317 * 318 * This system call is used to set parameters on a context, including 319 * superblock settings, data source and security labelling. 320 * 321 * Actions include triggering the creation of a superblock and the 322 * reconfiguration of the superblock attached to the specified context. 323 * 324 * When setting a parameter, @cmd indicates the type of value being proposed 325 * and @_key indicates the parameter to be altered. 326 * 327 * @_value and @aux are used to specify the value, should a value be required: 328 * 329 * (*) fsconfig_set_flag: No value is specified. The parameter must be boolean 330 * in nature. The key may be prefixed with "no" to invert the 331 * setting. @_value must be NULL and @aux must be 0. 332 * 333 * (*) fsconfig_set_string: A string value is specified. The parameter can be 334 * expecting boolean, integer, string or take a path. A conversion to an 335 * appropriate type will be attempted (which may include looking up as a 336 * path). @_value points to a NUL-terminated string and @aux must be 0. 337 * 338 * (*) fsconfig_set_binary: A binary blob is specified. @_value points to the 339 * blob and @aux indicates its size. The parameter must be expecting a 340 * blob. 341 * 342 * (*) fsconfig_set_path: A non-empty path is specified. The parameter must be 343 * expecting a path object. @_value points to a NUL-terminated string that 344 * is the path and @aux is a file descriptor at which to start a relative 345 * lookup or AT_FDCWD. 346 * 347 * (*) fsconfig_set_path_empty: As fsconfig_set_path, but with AT_EMPTY_PATH 348 * implied. 349 * 350 * (*) fsconfig_set_fd: An open file descriptor is specified. @_value must be 351 * NULL and @aux indicates the file descriptor. 352 */ 353 SYSCALL_DEFINE5(fsconfig, 354 int, fd, 355 unsigned int, cmd, 356 const char __user *, _key, 357 const void __user *, _value, 358 int, aux) 359 { 360 struct fs_context *fc; 361 int ret; 362 int lookup_flags = 0; 363 364 struct fs_parameter param = { 365 .type = fs_value_is_undefined, 366 }; 367 368 if (fd < 0) 369 return -EINVAL; 370 371 switch (cmd) { 372 case FSCONFIG_SET_FLAG: 373 if (!_key || _value || aux) 374 return -EINVAL; 375 break; 376 case FSCONFIG_SET_STRING: 377 if (!_key || !_value || aux) 378 return -EINVAL; 379 break; 380 case FSCONFIG_SET_BINARY: 381 if (!_key || !_value || aux <= 0 || aux > 1024 * 1024) 382 return -EINVAL; 383 break; 384 case FSCONFIG_SET_PATH: 385 case FSCONFIG_SET_PATH_EMPTY: 386 if (!_key || !_value || (aux != AT_FDCWD && aux < 0)) 387 return -EINVAL; 388 break; 389 case FSCONFIG_SET_FD: 390 if (!_key || _value || aux < 0) 391 return -EINVAL; 392 break; 393 case FSCONFIG_CMD_CREATE: 394 case FSCONFIG_CMD_CREATE_EXCL: 395 case FSCONFIG_CMD_RECONFIGURE: 396 if (_key || _value || aux) 397 return -EINVAL; 398 break; 399 default: 400 return -EOPNOTSUPP; 401 } 402 403 CLASS(fd, f)(fd); 404 if (fd_empty(f)) 405 return -EBADF; 406 if (fd_file(f)->f_op != &fscontext_fops) 407 return -EINVAL; 408 409 fc = fd_file(f)->private_data; 410 411 if (_key) { 412 param.key = strndup_user(_key, 256); 413 if (IS_ERR(param.key)) 414 return PTR_ERR(param.key); 415 } 416 417 switch (cmd) { 418 case FSCONFIG_SET_FLAG: 419 param.type = fs_value_is_flag; 420 break; 421 case FSCONFIG_SET_STRING: 422 param.type = fs_value_is_string; 423 param.string = strndup_user(_value, 256); 424 if (IS_ERR(param.string)) { 425 ret = PTR_ERR(param.string); 426 goto out_key; 427 } 428 param.size = strlen(param.string); 429 break; 430 case FSCONFIG_SET_BINARY: 431 param.type = fs_value_is_blob; 432 param.size = aux; 433 param.blob = memdup_user_nul(_value, aux); 434 if (IS_ERR(param.blob)) { 435 ret = PTR_ERR(param.blob); 436 goto out_key; 437 } 438 break; 439 case FSCONFIG_SET_PATH_EMPTY: 440 lookup_flags = LOOKUP_EMPTY; 441 fallthrough; 442 case FSCONFIG_SET_PATH: 443 param.type = fs_value_is_filename; 444 param.name = getname_flags(_value, lookup_flags); 445 if (IS_ERR(param.name)) { 446 ret = PTR_ERR(param.name); 447 goto out_key; 448 } 449 param.dirfd = aux; 450 param.size = strlen(param.name->name); 451 break; 452 case FSCONFIG_SET_FD: 453 param.type = fs_value_is_file; 454 ret = -EBADF; 455 param.file = fget_raw(aux); 456 if (!param.file) 457 goto out_key; 458 param.dirfd = aux; 459 break; 460 default: 461 break; 462 } 463 464 ret = mutex_lock_interruptible(&fc->uapi_mutex); 465 if (ret == 0) { 466 ret = vfs_fsconfig_locked(fc, cmd, ¶m); 467 mutex_unlock(&fc->uapi_mutex); 468 } 469 470 /* Clean up the our record of any value that we obtained from 471 * userspace. Note that the value may have been stolen by the LSM or 472 * filesystem, in which case the value pointer will have been cleared. 473 */ 474 switch (cmd) { 475 case FSCONFIG_SET_STRING: 476 case FSCONFIG_SET_BINARY: 477 kfree(param.string); 478 break; 479 case FSCONFIG_SET_PATH: 480 case FSCONFIG_SET_PATH_EMPTY: 481 if (param.name) 482 putname(param.name); 483 break; 484 case FSCONFIG_SET_FD: 485 if (param.file) 486 fput(param.file); 487 break; 488 default: 489 break; 490 } 491 out_key: 492 kfree(param.key); 493 return ret; 494 } 495