0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/fs_context.h>
0009 #include <linux/fs_parser.h>
0010 #include <linux/slab.h>
0011 #include <linux/uaccess.h>
0012 #include <linux/syscalls.h>
0013 #include <linux/security.h>
0014 #include <linux/anon_inodes.h>
0015 #include <linux/namei.h>
0016 #include <linux/file.h>
0017 #include <uapi/linux/mount.h>
0018 #include "internal.h"
0019 #include "mount.h"
0020
0021
0022
0023
0024 static ssize_t fscontext_read(struct file *file,
0025 char __user *_buf, size_t len, loff_t *pos)
0026 {
0027 struct fs_context *fc = file->private_data;
0028 struct fc_log *log = fc->log.log;
0029 unsigned int logsize = ARRAY_SIZE(log->buffer);
0030 ssize_t ret;
0031 char *p;
0032 bool need_free;
0033 int index, n;
0034
0035 ret = mutex_lock_interruptible(&fc->uapi_mutex);
0036 if (ret < 0)
0037 return ret;
0038
0039 if (log->head == log->tail) {
0040 mutex_unlock(&fc->uapi_mutex);
0041 return -ENODATA;
0042 }
0043
0044 index = log->tail & (logsize - 1);
0045 p = log->buffer[index];
0046 need_free = log->need_free & (1 << index);
0047 log->buffer[index] = NULL;
0048 log->need_free &= ~(1 << index);
0049 log->tail++;
0050 mutex_unlock(&fc->uapi_mutex);
0051
0052 ret = -EMSGSIZE;
0053 n = strlen(p);
0054 if (n > len)
0055 goto err_free;
0056 ret = -EFAULT;
0057 if (copy_to_user(_buf, p, n) != 0)
0058 goto err_free;
0059 ret = n;
0060
0061 err_free:
0062 if (need_free)
0063 kfree(p);
0064 return ret;
0065 }
0066
0067 static int fscontext_release(struct inode *inode, struct file *file)
0068 {
0069 struct fs_context *fc = file->private_data;
0070
0071 if (fc) {
0072 file->private_data = NULL;
0073 put_fs_context(fc);
0074 }
0075 return 0;
0076 }
0077
0078 const struct file_operations fscontext_fops = {
0079 .read = fscontext_read,
0080 .release = fscontext_release,
0081 .llseek = no_llseek,
0082 };
0083
0084
0085
0086
0087 static int fscontext_create_fd(struct fs_context *fc, unsigned int o_flags)
0088 {
0089 int fd;
0090
0091 fd = anon_inode_getfd("[fscontext]", &fscontext_fops, fc,
0092 O_RDWR | o_flags);
0093 if (fd < 0)
0094 put_fs_context(fc);
0095 return fd;
0096 }
0097
0098 static int fscontext_alloc_log(struct fs_context *fc)
0099 {
0100 fc->log.log = kzalloc(sizeof(*fc->log.log), GFP_KERNEL);
0101 if (!fc->log.log)
0102 return -ENOMEM;
0103 refcount_set(&fc->log.log->usage, 1);
0104 fc->log.log->owner = fc->fs_type->owner;
0105 return 0;
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115 SYSCALL_DEFINE2(fsopen, const char __user *, _fs_name, unsigned int, flags)
0116 {
0117 struct file_system_type *fs_type;
0118 struct fs_context *fc;
0119 const char *fs_name;
0120 int ret;
0121
0122 if (!may_mount())
0123 return -EPERM;
0124
0125 if (flags & ~FSOPEN_CLOEXEC)
0126 return -EINVAL;
0127
0128 fs_name = strndup_user(_fs_name, PAGE_SIZE);
0129 if (IS_ERR(fs_name))
0130 return PTR_ERR(fs_name);
0131
0132 fs_type = get_fs_type(fs_name);
0133 kfree(fs_name);
0134 if (!fs_type)
0135 return -ENODEV;
0136
0137 fc = fs_context_for_mount(fs_type, 0);
0138 put_filesystem(fs_type);
0139 if (IS_ERR(fc))
0140 return PTR_ERR(fc);
0141
0142 fc->phase = FS_CONTEXT_CREATE_PARAMS;
0143
0144 ret = fscontext_alloc_log(fc);
0145 if (ret < 0)
0146 goto err_fc;
0147
0148 return fscontext_create_fd(fc, flags & FSOPEN_CLOEXEC ? O_CLOEXEC : 0);
0149
0150 err_fc:
0151 put_fs_context(fc);
0152 return ret;
0153 }
0154
0155
0156
0157
0158 SYSCALL_DEFINE3(fspick, int, dfd, const char __user *, path, unsigned int, flags)
0159 {
0160 struct fs_context *fc;
0161 struct path target;
0162 unsigned int lookup_flags;
0163 int ret;
0164
0165 if (!may_mount())
0166 return -EPERM;
0167
0168 if ((flags & ~(FSPICK_CLOEXEC |
0169 FSPICK_SYMLINK_NOFOLLOW |
0170 FSPICK_NO_AUTOMOUNT |
0171 FSPICK_EMPTY_PATH)) != 0)
0172 return -EINVAL;
0173
0174 lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
0175 if (flags & FSPICK_SYMLINK_NOFOLLOW)
0176 lookup_flags &= ~LOOKUP_FOLLOW;
0177 if (flags & FSPICK_NO_AUTOMOUNT)
0178 lookup_flags &= ~LOOKUP_AUTOMOUNT;
0179 if (flags & FSPICK_EMPTY_PATH)
0180 lookup_flags |= LOOKUP_EMPTY;
0181 ret = user_path_at(dfd, path, lookup_flags, &target);
0182 if (ret < 0)
0183 goto err;
0184
0185 ret = -EINVAL;
0186 if (target.mnt->mnt_root != target.dentry)
0187 goto err_path;
0188
0189 fc = fs_context_for_reconfigure(target.dentry, 0, 0);
0190 if (IS_ERR(fc)) {
0191 ret = PTR_ERR(fc);
0192 goto err_path;
0193 }
0194
0195 fc->phase = FS_CONTEXT_RECONF_PARAMS;
0196
0197 ret = fscontext_alloc_log(fc);
0198 if (ret < 0)
0199 goto err_fc;
0200
0201 path_put(&target);
0202 return fscontext_create_fd(fc, flags & FSPICK_CLOEXEC ? O_CLOEXEC : 0);
0203
0204 err_fc:
0205 put_fs_context(fc);
0206 err_path:
0207 path_put(&target);
0208 err:
0209 return ret;
0210 }
0211
0212
0213
0214
0215
0216 static int vfs_fsconfig_locked(struct fs_context *fc, int cmd,
0217 struct fs_parameter *param)
0218 {
0219 struct super_block *sb;
0220 int ret;
0221
0222 ret = finish_clean_context(fc);
0223 if (ret)
0224 return ret;
0225 switch (cmd) {
0226 case FSCONFIG_CMD_CREATE:
0227 if (fc->phase != FS_CONTEXT_CREATE_PARAMS)
0228 return -EBUSY;
0229 if (!mount_capable(fc))
0230 return -EPERM;
0231 fc->phase = FS_CONTEXT_CREATING;
0232 ret = vfs_get_tree(fc);
0233 if (ret)
0234 break;
0235 sb = fc->root->d_sb;
0236 ret = security_sb_kern_mount(sb);
0237 if (unlikely(ret)) {
0238 fc_drop_locked(fc);
0239 break;
0240 }
0241 up_write(&sb->s_umount);
0242 fc->phase = FS_CONTEXT_AWAITING_MOUNT;
0243 return 0;
0244 case FSCONFIG_CMD_RECONFIGURE:
0245 if (fc->phase != FS_CONTEXT_RECONF_PARAMS)
0246 return -EBUSY;
0247 fc->phase = FS_CONTEXT_RECONFIGURING;
0248 sb = fc->root->d_sb;
0249 if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) {
0250 ret = -EPERM;
0251 break;
0252 }
0253 down_write(&sb->s_umount);
0254 ret = reconfigure_super(fc);
0255 up_write(&sb->s_umount);
0256 if (ret)
0257 break;
0258 vfs_clean_context(fc);
0259 return 0;
0260 default:
0261 if (fc->phase != FS_CONTEXT_CREATE_PARAMS &&
0262 fc->phase != FS_CONTEXT_RECONF_PARAMS)
0263 return -EBUSY;
0264
0265 return vfs_parse_fs_param(fc, param);
0266 }
0267 fc->phase = FS_CONTEXT_FAILED;
0268 return ret;
0269 }
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314 SYSCALL_DEFINE5(fsconfig,
0315 int, fd,
0316 unsigned int, cmd,
0317 const char __user *, _key,
0318 const void __user *, _value,
0319 int, aux)
0320 {
0321 struct fs_context *fc;
0322 struct fd f;
0323 int ret;
0324 int lookup_flags = 0;
0325
0326 struct fs_parameter param = {
0327 .type = fs_value_is_undefined,
0328 };
0329
0330 if (fd < 0)
0331 return -EINVAL;
0332
0333 switch (cmd) {
0334 case FSCONFIG_SET_FLAG:
0335 if (!_key || _value || aux)
0336 return -EINVAL;
0337 break;
0338 case FSCONFIG_SET_STRING:
0339 if (!_key || !_value || aux)
0340 return -EINVAL;
0341 break;
0342 case FSCONFIG_SET_BINARY:
0343 if (!_key || !_value || aux <= 0 || aux > 1024 * 1024)
0344 return -EINVAL;
0345 break;
0346 case FSCONFIG_SET_PATH:
0347 case FSCONFIG_SET_PATH_EMPTY:
0348 if (!_key || !_value || (aux != AT_FDCWD && aux < 0))
0349 return -EINVAL;
0350 break;
0351 case FSCONFIG_SET_FD:
0352 if (!_key || _value || aux < 0)
0353 return -EINVAL;
0354 break;
0355 case FSCONFIG_CMD_CREATE:
0356 case FSCONFIG_CMD_RECONFIGURE:
0357 if (_key || _value || aux)
0358 return -EINVAL;
0359 break;
0360 default:
0361 return -EOPNOTSUPP;
0362 }
0363
0364 f = fdget(fd);
0365 if (!f.file)
0366 return -EBADF;
0367 ret = -EINVAL;
0368 if (f.file->f_op != &fscontext_fops)
0369 goto out_f;
0370
0371 fc = f.file->private_data;
0372 if (fc->ops == &legacy_fs_context_ops) {
0373 switch (cmd) {
0374 case FSCONFIG_SET_BINARY:
0375 case FSCONFIG_SET_PATH:
0376 case FSCONFIG_SET_PATH_EMPTY:
0377 case FSCONFIG_SET_FD:
0378 ret = -EOPNOTSUPP;
0379 goto out_f;
0380 }
0381 }
0382
0383 if (_key) {
0384 param.key = strndup_user(_key, 256);
0385 if (IS_ERR(param.key)) {
0386 ret = PTR_ERR(param.key);
0387 goto out_f;
0388 }
0389 }
0390
0391 switch (cmd) {
0392 case FSCONFIG_SET_FLAG:
0393 param.type = fs_value_is_flag;
0394 break;
0395 case FSCONFIG_SET_STRING:
0396 param.type = fs_value_is_string;
0397 param.string = strndup_user(_value, 256);
0398 if (IS_ERR(param.string)) {
0399 ret = PTR_ERR(param.string);
0400 goto out_key;
0401 }
0402 param.size = strlen(param.string);
0403 break;
0404 case FSCONFIG_SET_BINARY:
0405 param.type = fs_value_is_blob;
0406 param.size = aux;
0407 param.blob = memdup_user_nul(_value, aux);
0408 if (IS_ERR(param.blob)) {
0409 ret = PTR_ERR(param.blob);
0410 goto out_key;
0411 }
0412 break;
0413 case FSCONFIG_SET_PATH_EMPTY:
0414 lookup_flags = LOOKUP_EMPTY;
0415 fallthrough;
0416 case FSCONFIG_SET_PATH:
0417 param.type = fs_value_is_filename;
0418 param.name = getname_flags(_value, lookup_flags, NULL);
0419 if (IS_ERR(param.name)) {
0420 ret = PTR_ERR(param.name);
0421 goto out_key;
0422 }
0423 param.dirfd = aux;
0424 param.size = strlen(param.name->name);
0425 break;
0426 case FSCONFIG_SET_FD:
0427 param.type = fs_value_is_file;
0428 ret = -EBADF;
0429 param.file = fget(aux);
0430 if (!param.file)
0431 goto out_key;
0432 break;
0433 default:
0434 break;
0435 }
0436
0437 ret = mutex_lock_interruptible(&fc->uapi_mutex);
0438 if (ret == 0) {
0439 ret = vfs_fsconfig_locked(fc, cmd, ¶m);
0440 mutex_unlock(&fc->uapi_mutex);
0441 }
0442
0443
0444
0445
0446
0447 switch (cmd) {
0448 case FSCONFIG_SET_STRING:
0449 case FSCONFIG_SET_BINARY:
0450 kfree(param.string);
0451 break;
0452 case FSCONFIG_SET_PATH:
0453 case FSCONFIG_SET_PATH_EMPTY:
0454 if (param.name)
0455 putname(param.name);
0456 break;
0457 case FSCONFIG_SET_FD:
0458 if (param.file)
0459 fput(param.file);
0460 break;
0461 default:
0462 break;
0463 }
0464 out_key:
0465 kfree(param.key);
0466 out_f:
0467 fdput(f);
0468 return ret;
0469 }