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