1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* -*- mode: c; c-basic-offset: 8; -*- 3 * vim: noexpandtab sw=8 ts=8 sts=0: 4 * 5 * symlink.c - operations for configfs symlinks. 6 * 7 * Based on sysfs: 8 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel 9 * 10 * configfs Copyright (C) 2005 Oracle. All rights reserved. 11 */ 12 13 #include <linux/fs.h> 14 #include <linux/module.h> 15 #include <linux/namei.h> 16 #include <linux/slab.h> 17 18 #include <linux/configfs.h> 19 #include "configfs_internal.h" 20 21 /* Protects attachments of new symlinks */ 22 DEFINE_MUTEX(configfs_symlink_mutex); 23 24 static int item_depth(struct config_item * item) 25 { 26 struct config_item * p = item; 27 int depth = 0; 28 do { depth++; } while ((p = p->ci_parent) && !configfs_is_root(p)); 29 return depth; 30 } 31 32 static int item_path_length(struct config_item * item) 33 { 34 struct config_item * p = item; 35 int length = 1; 36 do { 37 length += strlen(config_item_name(p)) + 1; 38 p = p->ci_parent; 39 } while (p && !configfs_is_root(p)); 40 return length; 41 } 42 43 static void fill_item_path(struct config_item * item, char * buffer, int length) 44 { 45 struct config_item * p; 46 47 --length; 48 for (p = item; p && !configfs_is_root(p); p = p->ci_parent) { 49 int cur = strlen(config_item_name(p)); 50 51 /* back up enough to print this bus id with '/' */ 52 length -= cur; 53 memcpy(buffer + length, config_item_name(p), cur); 54 *(buffer + --length) = '/'; 55 } 56 } 57 58 static int configfs_get_target_path(struct config_item *item, 59 struct config_item *target, char *path) 60 { 61 int depth, size; 62 char *s; 63 64 depth = item_depth(item); 65 size = item_path_length(target) + depth * 3 - 1; 66 if (size > PATH_MAX) 67 return -ENAMETOOLONG; 68 69 pr_debug("%s: depth = %d, size = %d\n", __func__, depth, size); 70 71 for (s = path; depth--; s += 3) 72 strcpy(s,"../"); 73 74 fill_item_path(target, path, size); 75 pr_debug("%s: path = '%s'\n", __func__, path); 76 return 0; 77 } 78 79 static int create_link(struct config_item *parent_item, 80 struct config_item *item, 81 struct dentry *dentry) 82 { 83 struct configfs_dirent *target_sd = item->ci_dentry->d_fsdata; 84 char *body; 85 int ret; 86 87 if (!configfs_dirent_is_ready(target_sd)) 88 return -ENOENT; 89 90 body = kzalloc(PAGE_SIZE, GFP_KERNEL); 91 if (!body) 92 return -ENOMEM; 93 94 configfs_get(target_sd); 95 spin_lock(&configfs_dirent_lock); 96 if (target_sd->s_type & CONFIGFS_USET_DROPPING) { 97 spin_unlock(&configfs_dirent_lock); 98 configfs_put(target_sd); 99 kfree(body); 100 return -ENOENT; 101 } 102 target_sd->s_links++; 103 spin_unlock(&configfs_dirent_lock); 104 ret = configfs_get_target_path(parent_item, item, body); 105 if (!ret) 106 ret = configfs_create_link(target_sd, parent_item->ci_dentry, 107 dentry, body); 108 if (ret) { 109 spin_lock(&configfs_dirent_lock); 110 target_sd->s_links--; 111 spin_unlock(&configfs_dirent_lock); 112 configfs_put(target_sd); 113 kfree(body); 114 } 115 return ret; 116 } 117 118 119 static int get_target(const char *symname, struct path *path, 120 struct config_item **target, struct super_block *sb) 121 { 122 int ret; 123 124 ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path); 125 if (!ret) { 126 if (path->dentry->d_sb == sb) { 127 *target = configfs_get_config_item(path->dentry); 128 if (!*target) { 129 ret = -ENOENT; 130 path_put(path); 131 } 132 } else { 133 ret = -EPERM; 134 path_put(path); 135 } 136 } 137 138 return ret; 139 } 140 141 142 int configfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, 143 struct dentry *dentry, const char *symname) 144 { 145 int ret; 146 struct path path; 147 struct configfs_dirent *sd; 148 struct config_item *parent_item; 149 struct config_item *target_item = NULL; 150 const struct config_item_type *type; 151 152 sd = dentry->d_parent->d_fsdata; 153 /* 154 * Fake invisibility if dir belongs to a group/default groups hierarchy 155 * being attached 156 */ 157 if (!configfs_dirent_is_ready(sd)) 158 return -ENOENT; 159 160 parent_item = configfs_get_config_item(dentry->d_parent); 161 type = parent_item->ci_type; 162 163 ret = -EPERM; 164 if (!type || !type->ct_item_ops || 165 !type->ct_item_ops->allow_link) 166 goto out_put; 167 168 /* 169 * This is really sick. What they wanted was a hybrid of 170 * link(2) and symlink(2) - they wanted the target resolved 171 * at syscall time (as link(2) would've done), be a directory 172 * (which link(2) would've refused to do) *AND* be a deep 173 * fucking magic, making the target busy from rmdir POV. 174 * symlink(2) is nothing of that sort, and the locking it 175 * gets matches the normal symlink(2) semantics. Without 176 * attempts to resolve the target (which might very well 177 * not even exist yet) done prior to locking the parent 178 * directory. This perversion, OTOH, needs to resolve 179 * the target, which would lead to obvious deadlocks if 180 * attempted with any directories locked. 181 * 182 * Unfortunately, that garbage is userland ABI and we should've 183 * said "no" back in 2005. Too late now, so we get to 184 * play very ugly games with locking. 185 * 186 * Try *ANYTHING* of that sort in new code, and you will 187 * really regret it. Just ask yourself - what could a BOFH 188 * do to me and do I want to find it out first-hand? 189 * 190 * AV, a thoroughly annoyed bastard. 191 */ 192 inode_unlock(dir); 193 ret = get_target(symname, &path, &target_item, dentry->d_sb); 194 inode_lock(dir); 195 if (ret) 196 goto out_put; 197 198 if (dentry->d_inode || d_unhashed(dentry)) 199 ret = -EEXIST; 200 else 201 ret = inode_permission(&init_user_ns, dir, 202 MAY_WRITE | MAY_EXEC); 203 if (!ret) 204 ret = type->ct_item_ops->allow_link(parent_item, target_item); 205 if (!ret) { 206 mutex_lock(&configfs_symlink_mutex); 207 ret = create_link(parent_item, target_item, dentry); 208 mutex_unlock(&configfs_symlink_mutex); 209 if (ret && type->ct_item_ops->drop_link) 210 type->ct_item_ops->drop_link(parent_item, 211 target_item); 212 } 213 214 config_item_put(target_item); 215 path_put(&path); 216 217 out_put: 218 config_item_put(parent_item); 219 return ret; 220 } 221 222 int configfs_unlink(struct inode *dir, struct dentry *dentry) 223 { 224 struct configfs_dirent *sd = dentry->d_fsdata, *target_sd; 225 struct config_item *parent_item; 226 const struct config_item_type *type; 227 int ret; 228 229 ret = -EPERM; /* What lack-of-symlink returns */ 230 if (!(sd->s_type & CONFIGFS_ITEM_LINK)) 231 goto out; 232 233 target_sd = sd->s_element; 234 235 parent_item = configfs_get_config_item(dentry->d_parent); 236 type = parent_item->ci_type; 237 238 spin_lock(&configfs_dirent_lock); 239 list_del_init(&sd->s_sibling); 240 spin_unlock(&configfs_dirent_lock); 241 configfs_drop_dentry(sd, dentry->d_parent); 242 dput(dentry); 243 configfs_put(sd); 244 245 /* 246 * drop_link() must be called before 247 * decrementing target's ->s_links, so that the order of 248 * drop_link(this, target) and drop_item(target) is preserved. 249 */ 250 if (type && type->ct_item_ops && 251 type->ct_item_ops->drop_link) 252 type->ct_item_ops->drop_link(parent_item, 253 target_sd->s_element); 254 255 spin_lock(&configfs_dirent_lock); 256 target_sd->s_links--; 257 spin_unlock(&configfs_dirent_lock); 258 configfs_put(target_sd); 259 260 config_item_put(parent_item); 261 262 ret = 0; 263 264 out: 265 return ret; 266 } 267 268 const struct inode_operations configfs_symlink_inode_operations = { 269 .get_link = simple_get_link, 270 .setattr = configfs_setattr, 271 }; 272 273