1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 FUSE: Filesystem in Userspace 4 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 5 */ 6 7 #include "fuse_i.h" 8 #include "dev.h" 9 10 #include <linux/init.h> 11 #include <linux/module.h> 12 #include <linux/fs_context.h> 13 #include <linux/namei.h> 14 15 #define FUSE_CTL_SUPER_MAGIC 0x65735543 16 17 /* 18 * This is non-NULL when the single instance of the control filesystem 19 * exists. Protected by fuse_mutex 20 */ 21 static struct super_block *fuse_control_sb; 22 23 static struct fuse_conn *fuse_ctl_file_conn_get(struct file *file) 24 { 25 struct fuse_conn *fc; 26 mutex_lock(&fuse_mutex); 27 fc = file_inode(file)->i_private; 28 if (fc) 29 fc = fuse_conn_get(fc); 30 mutex_unlock(&fuse_mutex); 31 return fc; 32 } 33 34 static ssize_t fuse_conn_abort_write(struct file *file, const char __user *buf, 35 size_t count, loff_t *ppos) 36 { 37 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 38 if (fc) { 39 fuse_chan_abort(fc->chan, fc->abort_err); 40 fuse_conn_put(fc); 41 } 42 return count; 43 } 44 45 static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf, 46 size_t len, loff_t *ppos) 47 { 48 char tmp[32]; 49 size_t size; 50 51 if (!*ppos) { 52 long value; 53 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 54 if (!fc) 55 return 0; 56 57 value = fuse_chan_num_waiting(fc->chan); 58 file->private_data = (void *)value; 59 fuse_conn_put(fc); 60 } 61 size = sprintf(tmp, "%ld\n", (long)file->private_data); 62 return simple_read_from_buffer(buf, len, ppos, tmp, size); 63 } 64 65 static ssize_t fuse_conn_limit_read(struct file *file, char __user *buf, 66 size_t len, loff_t *ppos, unsigned val) 67 { 68 char tmp[32]; 69 size_t size = sprintf(tmp, "%u\n", val); 70 71 return simple_read_from_buffer(buf, len, ppos, tmp, size); 72 } 73 74 static ssize_t fuse_conn_limit_write(struct file *file, const char __user *buf, 75 size_t count, loff_t *ppos, unsigned *val, 76 unsigned global_limit) 77 { 78 unsigned long t; 79 unsigned limit = (1 << 16) - 1; 80 int err; 81 82 if (*ppos) 83 return -EINVAL; 84 85 err = kstrtoul_from_user(buf, count, 0, &t); 86 if (err) 87 return err; 88 89 if (!capable(CAP_SYS_ADMIN)) 90 limit = min(limit, global_limit); 91 92 if (t > limit) 93 return -EINVAL; 94 95 *val = t; 96 97 return count; 98 } 99 100 static ssize_t fuse_conn_max_background_read(struct file *file, 101 char __user *buf, size_t len, 102 loff_t *ppos) 103 { 104 struct fuse_conn *fc; 105 unsigned val; 106 107 fc = fuse_ctl_file_conn_get(file); 108 if (!fc) 109 return 0; 110 111 val = fuse_chan_max_background(fc->chan); 112 fuse_conn_put(fc); 113 114 return fuse_conn_limit_read(file, buf, len, ppos, val); 115 } 116 117 static ssize_t fuse_conn_max_background_write(struct file *file, 118 const char __user *buf, 119 size_t count, loff_t *ppos) 120 { 121 unsigned int val = 0; 122 ssize_t ret; 123 124 ret = fuse_conn_limit_write(file, buf, count, ppos, &val, 125 max_user_bgreq); 126 if (ret > 0) { 127 struct fuse_conn *fc = fuse_ctl_file_conn_get(file); 128 if (fc) { 129 fuse_chan_max_background_set(fc->chan, val); 130 fuse_conn_put(fc); 131 } 132 } 133 134 return ret; 135 } 136 137 static ssize_t fuse_conn_congestion_threshold_read(struct file *file, 138 char __user *buf, size_t len, 139 loff_t *ppos) 140 { 141 struct fuse_conn *fc; 142 unsigned val; 143 144 fc = fuse_ctl_file_conn_get(file); 145 if (!fc) 146 return 0; 147 148 val = READ_ONCE(fc->congestion_threshold); 149 fuse_conn_put(fc); 150 151 return fuse_conn_limit_read(file, buf, len, ppos, val); 152 } 153 154 static ssize_t fuse_conn_congestion_threshold_write(struct file *file, 155 const char __user *buf, 156 size_t count, loff_t *ppos) 157 { 158 unsigned int val = 0; 159 struct fuse_conn *fc; 160 ssize_t ret; 161 162 ret = fuse_conn_limit_write(file, buf, count, ppos, &val, 163 max_user_congthresh); 164 if (ret <= 0) 165 goto out; 166 fc = fuse_ctl_file_conn_get(file); 167 if (!fc) 168 goto out; 169 170 WRITE_ONCE(fc->congestion_threshold, val); 171 fuse_conn_put(fc); 172 out: 173 return ret; 174 } 175 176 static const struct file_operations fuse_ctl_abort_ops = { 177 .open = nonseekable_open, 178 .write = fuse_conn_abort_write, 179 }; 180 181 static const struct file_operations fuse_ctl_waiting_ops = { 182 .open = nonseekable_open, 183 .read = fuse_conn_waiting_read, 184 }; 185 186 static const struct file_operations fuse_conn_max_background_ops = { 187 .open = nonseekable_open, 188 .read = fuse_conn_max_background_read, 189 .write = fuse_conn_max_background_write, 190 }; 191 192 static const struct file_operations fuse_conn_congestion_threshold_ops = { 193 .open = nonseekable_open, 194 .read = fuse_conn_congestion_threshold_read, 195 .write = fuse_conn_congestion_threshold_write, 196 }; 197 198 static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, 199 struct fuse_conn *fc, 200 const char *name, int mode, 201 const struct inode_operations *iop, 202 const struct file_operations *fop) 203 { 204 struct dentry *dentry; 205 struct inode *inode; 206 207 dentry = d_alloc_name(parent, name); 208 if (!dentry) 209 return NULL; 210 211 inode = new_inode(fuse_control_sb); 212 if (!inode) { 213 dput(dentry); 214 return NULL; 215 } 216 217 inode->i_ino = get_next_ino(); 218 inode->i_mode = mode; 219 inode->i_uid = fc->user_id; 220 inode->i_gid = fc->group_id; 221 simple_inode_init_ts(inode); 222 /* setting ->i_op to NULL is not allowed */ 223 if (iop) 224 inode->i_op = iop; 225 inode->i_fop = fop; 226 if (S_ISDIR(mode)) { 227 inc_nlink(d_inode(parent)); 228 inc_nlink(inode); 229 } 230 inode->i_private = fc; 231 d_make_persistent(dentry, inode); 232 dput(dentry); 233 234 /* 235 * We are returning a borrowed reference here - it's only good while 236 * fuse_mutex is held. Actually it's d_make_persistent() return 237 * value... 238 */ 239 return dentry; 240 } 241 242 /* 243 * Add a connection to the control filesystem (if it exists). Caller 244 * must hold fuse_mutex 245 */ 246 int fuse_ctl_add_conn(struct fuse_conn *fc) 247 { 248 struct dentry *parent; 249 char name[32]; 250 251 if (!fuse_control_sb || fc->no_control) 252 return 0; 253 254 parent = fuse_control_sb->s_root; 255 sprintf(name, "%u", fc->dev); 256 parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 257 &simple_dir_inode_operations, 258 &simple_dir_operations); 259 if (!parent) 260 goto err; 261 262 if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 263 NULL, &fuse_ctl_waiting_ops) || 264 !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 265 NULL, &fuse_ctl_abort_ops) || 266 !fuse_ctl_add_dentry(parent, fc, "max_background", S_IFREG | 0600, 267 NULL, &fuse_conn_max_background_ops) || 268 !fuse_ctl_add_dentry(parent, fc, "congestion_threshold", 269 S_IFREG | 0600, NULL, 270 &fuse_conn_congestion_threshold_ops)) 271 goto err; 272 273 return 0; 274 275 err: 276 fuse_ctl_remove_conn(fc); 277 return -ENOMEM; 278 } 279 280 static void remove_one(struct dentry *dentry) 281 { 282 d_inode(dentry)->i_private = NULL; 283 } 284 285 /* 286 * Remove a connection from the control filesystem (if it exists). 287 * Caller must hold fuse_mutex 288 */ 289 void fuse_ctl_remove_conn(struct fuse_conn *fc) 290 { 291 char name[32]; 292 293 if (!fuse_control_sb || fc->no_control) 294 return; 295 296 sprintf(name, "%u", fc->dev); 297 simple_remove_by_name(fuse_control_sb->s_root, name, remove_one); 298 } 299 300 static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fsc) 301 { 302 static const struct tree_descr empty_descr = {""}; 303 struct fuse_conn *fc; 304 int err; 305 306 err = simple_fill_super(sb, FUSE_CTL_SUPER_MAGIC, &empty_descr); 307 if (err) 308 return err; 309 310 mutex_lock(&fuse_mutex); 311 BUG_ON(fuse_control_sb); 312 fuse_control_sb = sb; 313 list_for_each_entry(fc, &fuse_conn_list, entry) { 314 err = fuse_ctl_add_conn(fc); 315 if (err) { 316 fuse_control_sb = NULL; 317 mutex_unlock(&fuse_mutex); 318 return err; 319 } 320 } 321 mutex_unlock(&fuse_mutex); 322 323 return 0; 324 } 325 326 static int fuse_ctl_get_tree(struct fs_context *fsc) 327 { 328 return get_tree_single(fsc, fuse_ctl_fill_super); 329 } 330 331 static const struct fs_context_operations fuse_ctl_context_ops = { 332 .get_tree = fuse_ctl_get_tree, 333 }; 334 335 static int fuse_ctl_init_fs_context(struct fs_context *fsc) 336 { 337 fsc->ops = &fuse_ctl_context_ops; 338 return 0; 339 } 340 341 static void fuse_ctl_kill_sb(struct super_block *sb) 342 { 343 mutex_lock(&fuse_mutex); 344 fuse_control_sb = NULL; 345 mutex_unlock(&fuse_mutex); 346 347 kill_anon_super(sb); 348 } 349 350 static struct file_system_type fuse_ctl_fs_type = { 351 .owner = THIS_MODULE, 352 .name = "fusectl", 353 .init_fs_context = fuse_ctl_init_fs_context, 354 .kill_sb = fuse_ctl_kill_sb, 355 }; 356 MODULE_ALIAS_FS("fusectl"); 357 358 int __init fuse_ctl_init(void) 359 { 360 return register_filesystem(&fuse_ctl_fs_type); 361 } 362 363 void __exit fuse_ctl_cleanup(void) 364 { 365 unregister_filesystem(&fuse_ctl_fs_type); 366 } 367