root/fs/btrfs/xattr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. btrfs_getxattr
  2. btrfs_setxattr
  3. btrfs_setxattr_trans
  4. btrfs_listxattr
  5. btrfs_xattr_handler_get
  6. btrfs_xattr_handler_set
  7. btrfs_xattr_handler_set_prop
  8. btrfs_initxattrs
  9. btrfs_xattr_security_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2007 Red Hat.  All rights reserved.
   4  */
   5 
   6 #include <linux/init.h>
   7 #include <linux/fs.h>
   8 #include <linux/slab.h>
   9 #include <linux/rwsem.h>
  10 #include <linux/xattr.h>
  11 #include <linux/security.h>
  12 #include <linux/posix_acl_xattr.h>
  13 #include <linux/iversion.h>
  14 #include <linux/sched/mm.h>
  15 #include "ctree.h"
  16 #include "btrfs_inode.h"
  17 #include "transaction.h"
  18 #include "xattr.h"
  19 #include "disk-io.h"
  20 #include "props.h"
  21 #include "locking.h"
  22 
  23 int btrfs_getxattr(struct inode *inode, const char *name,
  24                                 void *buffer, size_t size)
  25 {
  26         struct btrfs_dir_item *di;
  27         struct btrfs_root *root = BTRFS_I(inode)->root;
  28         struct btrfs_path *path;
  29         struct extent_buffer *leaf;
  30         int ret = 0;
  31         unsigned long data_ptr;
  32 
  33         path = btrfs_alloc_path();
  34         if (!path)
  35                 return -ENOMEM;
  36 
  37         /* lookup the xattr by name */
  38         di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(BTRFS_I(inode)),
  39                         name, strlen(name), 0);
  40         if (!di) {
  41                 ret = -ENODATA;
  42                 goto out;
  43         } else if (IS_ERR(di)) {
  44                 ret = PTR_ERR(di);
  45                 goto out;
  46         }
  47 
  48         leaf = path->nodes[0];
  49         /* if size is 0, that means we want the size of the attr */
  50         if (!size) {
  51                 ret = btrfs_dir_data_len(leaf, di);
  52                 goto out;
  53         }
  54 
  55         /* now get the data out of our dir_item */
  56         if (btrfs_dir_data_len(leaf, di) > size) {
  57                 ret = -ERANGE;
  58                 goto out;
  59         }
  60 
  61         /*
  62          * The way things are packed into the leaf is like this
  63          * |struct btrfs_dir_item|name|data|
  64          * where name is the xattr name, so security.foo, and data is the
  65          * content of the xattr.  data_ptr points to the location in memory
  66          * where the data starts in the in memory leaf
  67          */
  68         data_ptr = (unsigned long)((char *)(di + 1) +
  69                                    btrfs_dir_name_len(leaf, di));
  70         read_extent_buffer(leaf, buffer, data_ptr,
  71                            btrfs_dir_data_len(leaf, di));
  72         ret = btrfs_dir_data_len(leaf, di);
  73 
  74 out:
  75         btrfs_free_path(path);
  76         return ret;
  77 }
  78 
  79 int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
  80                    const char *name, const void *value, size_t size, int flags)
  81 {
  82         struct btrfs_dir_item *di = NULL;
  83         struct btrfs_root *root = BTRFS_I(inode)->root;
  84         struct btrfs_fs_info *fs_info = root->fs_info;
  85         struct btrfs_path *path;
  86         size_t name_len = strlen(name);
  87         int ret = 0;
  88 
  89         ASSERT(trans);
  90 
  91         if (name_len + size > BTRFS_MAX_XATTR_SIZE(root->fs_info))
  92                 return -ENOSPC;
  93 
  94         path = btrfs_alloc_path();
  95         if (!path)
  96                 return -ENOMEM;
  97         path->skip_release_on_error = 1;
  98 
  99         if (!value) {
 100                 di = btrfs_lookup_xattr(trans, root, path,
 101                                 btrfs_ino(BTRFS_I(inode)), name, name_len, -1);
 102                 if (!di && (flags & XATTR_REPLACE))
 103                         ret = -ENODATA;
 104                 else if (IS_ERR(di))
 105                         ret = PTR_ERR(di);
 106                 else if (di)
 107                         ret = btrfs_delete_one_dir_name(trans, root, path, di);
 108                 goto out;
 109         }
 110 
 111         /*
 112          * For a replace we can't just do the insert blindly.
 113          * Do a lookup first (read-only btrfs_search_slot), and return if xattr
 114          * doesn't exist. If it exists, fall down below to the insert/replace
 115          * path - we can't race with a concurrent xattr delete, because the VFS
 116          * locks the inode's i_mutex before calling setxattr or removexattr.
 117          */
 118         if (flags & XATTR_REPLACE) {
 119                 ASSERT(inode_is_locked(inode));
 120                 di = btrfs_lookup_xattr(NULL, root, path,
 121                                 btrfs_ino(BTRFS_I(inode)), name, name_len, 0);
 122                 if (!di)
 123                         ret = -ENODATA;
 124                 else if (IS_ERR(di))
 125                         ret = PTR_ERR(di);
 126                 if (ret)
 127                         goto out;
 128                 btrfs_release_path(path);
 129                 di = NULL;
 130         }
 131 
 132         ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(BTRFS_I(inode)),
 133                                       name, name_len, value, size);
 134         if (ret == -EOVERFLOW) {
 135                 /*
 136                  * We have an existing item in a leaf, split_leaf couldn't
 137                  * expand it. That item might have or not a dir_item that
 138                  * matches our target xattr, so lets check.
 139                  */
 140                 ret = 0;
 141                 btrfs_assert_tree_locked(path->nodes[0]);
 142                 di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
 143                 if (!di && !(flags & XATTR_REPLACE)) {
 144                         ret = -ENOSPC;
 145                         goto out;
 146                 }
 147         } else if (ret == -EEXIST) {
 148                 ret = 0;
 149                 di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
 150                 ASSERT(di); /* logic error */
 151         } else if (ret) {
 152                 goto out;
 153         }
 154 
 155         if (di && (flags & XATTR_CREATE)) {
 156                 ret = -EEXIST;
 157                 goto out;
 158         }
 159 
 160         if (di) {
 161                 /*
 162                  * We're doing a replace, and it must be atomic, that is, at
 163                  * any point in time we have either the old or the new xattr
 164                  * value in the tree. We don't want readers (getxattr and
 165                  * listxattrs) to miss a value, this is specially important
 166                  * for ACLs.
 167                  */
 168                 const int slot = path->slots[0];
 169                 struct extent_buffer *leaf = path->nodes[0];
 170                 const u16 old_data_len = btrfs_dir_data_len(leaf, di);
 171                 const u32 item_size = btrfs_item_size_nr(leaf, slot);
 172                 const u32 data_size = sizeof(*di) + name_len + size;
 173                 struct btrfs_item *item;
 174                 unsigned long data_ptr;
 175                 char *ptr;
 176 
 177                 if (size > old_data_len) {
 178                         if (btrfs_leaf_free_space(leaf) <
 179                             (size - old_data_len)) {
 180                                 ret = -ENOSPC;
 181                                 goto out;
 182                         }
 183                 }
 184 
 185                 if (old_data_len + name_len + sizeof(*di) == item_size) {
 186                         /* No other xattrs packed in the same leaf item. */
 187                         if (size > old_data_len)
 188                                 btrfs_extend_item(path, size - old_data_len);
 189                         else if (size < old_data_len)
 190                                 btrfs_truncate_item(path, data_size, 1);
 191                 } else {
 192                         /* There are other xattrs packed in the same item. */
 193                         ret = btrfs_delete_one_dir_name(trans, root, path, di);
 194                         if (ret)
 195                                 goto out;
 196                         btrfs_extend_item(path, data_size);
 197                 }
 198 
 199                 item = btrfs_item_nr(slot);
 200                 ptr = btrfs_item_ptr(leaf, slot, char);
 201                 ptr += btrfs_item_size(leaf, item) - data_size;
 202                 di = (struct btrfs_dir_item *)ptr;
 203                 btrfs_set_dir_data_len(leaf, di, size);
 204                 data_ptr = ((unsigned long)(di + 1)) + name_len;
 205                 write_extent_buffer(leaf, value, data_ptr, size);
 206                 btrfs_mark_buffer_dirty(leaf);
 207         } else {
 208                 /*
 209                  * Insert, and we had space for the xattr, so path->slots[0] is
 210                  * where our xattr dir_item is and btrfs_insert_xattr_item()
 211                  * filled it.
 212                  */
 213         }
 214 out:
 215         btrfs_free_path(path);
 216         if (!ret)
 217                 set_bit(BTRFS_INODE_COPY_EVERYTHING,
 218                         &BTRFS_I(inode)->runtime_flags);
 219         return ret;
 220 }
 221 
 222 /*
 223  * @value: "" makes the attribute to empty, NULL removes it
 224  */
 225 int btrfs_setxattr_trans(struct inode *inode, const char *name,
 226                          const void *value, size_t size, int flags)
 227 {
 228         struct btrfs_root *root = BTRFS_I(inode)->root;
 229         struct btrfs_trans_handle *trans;
 230         int ret;
 231 
 232         trans = btrfs_start_transaction(root, 2);
 233         if (IS_ERR(trans))
 234                 return PTR_ERR(trans);
 235 
 236         ret = btrfs_setxattr(trans, inode, name, value, size, flags);
 237         if (ret)
 238                 goto out;
 239 
 240         inode_inc_iversion(inode);
 241         inode->i_ctime = current_time(inode);
 242         ret = btrfs_update_inode(trans, root, inode);
 243         BUG_ON(ret);
 244 out:
 245         btrfs_end_transaction(trans);
 246         return ret;
 247 }
 248 
 249 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 250 {
 251         struct btrfs_key key;
 252         struct inode *inode = d_inode(dentry);
 253         struct btrfs_root *root = BTRFS_I(inode)->root;
 254         struct btrfs_path *path;
 255         int ret = 0;
 256         size_t total_size = 0, size_left = size;
 257 
 258         /*
 259          * ok we want all objects associated with this id.
 260          * NOTE: we set key.offset = 0; because we want to start with the
 261          * first xattr that we find and walk forward
 262          */
 263         key.objectid = btrfs_ino(BTRFS_I(inode));
 264         key.type = BTRFS_XATTR_ITEM_KEY;
 265         key.offset = 0;
 266 
 267         path = btrfs_alloc_path();
 268         if (!path)
 269                 return -ENOMEM;
 270         path->reada = READA_FORWARD;
 271 
 272         /* search for our xattrs */
 273         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 274         if (ret < 0)
 275                 goto err;
 276 
 277         while (1) {
 278                 struct extent_buffer *leaf;
 279                 int slot;
 280                 struct btrfs_dir_item *di;
 281                 struct btrfs_key found_key;
 282                 u32 item_size;
 283                 u32 cur;
 284 
 285                 leaf = path->nodes[0];
 286                 slot = path->slots[0];
 287 
 288                 /* this is where we start walking through the path */
 289                 if (slot >= btrfs_header_nritems(leaf)) {
 290                         /*
 291                          * if we've reached the last slot in this leaf we need
 292                          * to go to the next leaf and reset everything
 293                          */
 294                         ret = btrfs_next_leaf(root, path);
 295                         if (ret < 0)
 296                                 goto err;
 297                         else if (ret > 0)
 298                                 break;
 299                         continue;
 300                 }
 301 
 302                 btrfs_item_key_to_cpu(leaf, &found_key, slot);
 303 
 304                 /* check to make sure this item is what we want */
 305                 if (found_key.objectid != key.objectid)
 306                         break;
 307                 if (found_key.type > BTRFS_XATTR_ITEM_KEY)
 308                         break;
 309                 if (found_key.type < BTRFS_XATTR_ITEM_KEY)
 310                         goto next_item;
 311 
 312                 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
 313                 item_size = btrfs_item_size_nr(leaf, slot);
 314                 cur = 0;
 315                 while (cur < item_size) {
 316                         u16 name_len = btrfs_dir_name_len(leaf, di);
 317                         u16 data_len = btrfs_dir_data_len(leaf, di);
 318                         u32 this_len = sizeof(*di) + name_len + data_len;
 319                         unsigned long name_ptr = (unsigned long)(di + 1);
 320 
 321                         total_size += name_len + 1;
 322                         /*
 323                          * We are just looking for how big our buffer needs to
 324                          * be.
 325                          */
 326                         if (!size)
 327                                 goto next;
 328 
 329                         if (!buffer || (name_len + 1) > size_left) {
 330                                 ret = -ERANGE;
 331                                 goto err;
 332                         }
 333 
 334                         read_extent_buffer(leaf, buffer, name_ptr, name_len);
 335                         buffer[name_len] = '\0';
 336 
 337                         size_left -= name_len + 1;
 338                         buffer += name_len + 1;
 339 next:
 340                         cur += this_len;
 341                         di = (struct btrfs_dir_item *)((char *)di + this_len);
 342                 }
 343 next_item:
 344                 path->slots[0]++;
 345         }
 346         ret = total_size;
 347 
 348 err:
 349         btrfs_free_path(path);
 350 
 351         return ret;
 352 }
 353 
 354 static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
 355                                    struct dentry *unused, struct inode *inode,
 356                                    const char *name, void *buffer, size_t size)
 357 {
 358         name = xattr_full_name(handler, name);
 359         return btrfs_getxattr(inode, name, buffer, size);
 360 }
 361 
 362 static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
 363                                    struct dentry *unused, struct inode *inode,
 364                                    const char *name, const void *buffer,
 365                                    size_t size, int flags)
 366 {
 367         name = xattr_full_name(handler, name);
 368         return btrfs_setxattr_trans(inode, name, buffer, size, flags);
 369 }
 370 
 371 static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
 372                                         struct dentry *unused, struct inode *inode,
 373                                         const char *name, const void *value,
 374                                         size_t size, int flags)
 375 {
 376         int ret;
 377         struct btrfs_trans_handle *trans;
 378         struct btrfs_root *root = BTRFS_I(inode)->root;
 379 
 380         name = xattr_full_name(handler, name);
 381         ret = btrfs_validate_prop(name, value, size);
 382         if (ret)
 383                 return ret;
 384 
 385         trans = btrfs_start_transaction(root, 2);
 386         if (IS_ERR(trans))
 387                 return PTR_ERR(trans);
 388 
 389         ret = btrfs_set_prop(trans, inode, name, value, size, flags);
 390         if (!ret) {
 391                 inode_inc_iversion(inode);
 392                 inode->i_ctime = current_time(inode);
 393                 ret = btrfs_update_inode(trans, root, inode);
 394                 BUG_ON(ret);
 395         }
 396 
 397         btrfs_end_transaction(trans);
 398 
 399         return ret;
 400 }
 401 
 402 static const struct xattr_handler btrfs_security_xattr_handler = {
 403         .prefix = XATTR_SECURITY_PREFIX,
 404         .get = btrfs_xattr_handler_get,
 405         .set = btrfs_xattr_handler_set,
 406 };
 407 
 408 static const struct xattr_handler btrfs_trusted_xattr_handler = {
 409         .prefix = XATTR_TRUSTED_PREFIX,
 410         .get = btrfs_xattr_handler_get,
 411         .set = btrfs_xattr_handler_set,
 412 };
 413 
 414 static const struct xattr_handler btrfs_user_xattr_handler = {
 415         .prefix = XATTR_USER_PREFIX,
 416         .get = btrfs_xattr_handler_get,
 417         .set = btrfs_xattr_handler_set,
 418 };
 419 
 420 static const struct xattr_handler btrfs_btrfs_xattr_handler = {
 421         .prefix = XATTR_BTRFS_PREFIX,
 422         .get = btrfs_xattr_handler_get,
 423         .set = btrfs_xattr_handler_set_prop,
 424 };
 425 
 426 const struct xattr_handler *btrfs_xattr_handlers[] = {
 427         &btrfs_security_xattr_handler,
 428 #ifdef CONFIG_BTRFS_FS_POSIX_ACL
 429         &posix_acl_access_xattr_handler,
 430         &posix_acl_default_xattr_handler,
 431 #endif
 432         &btrfs_trusted_xattr_handler,
 433         &btrfs_user_xattr_handler,
 434         &btrfs_btrfs_xattr_handler,
 435         NULL,
 436 };
 437 
 438 static int btrfs_initxattrs(struct inode *inode,
 439                             const struct xattr *xattr_array, void *fs_private)
 440 {
 441         struct btrfs_trans_handle *trans = fs_private;
 442         const struct xattr *xattr;
 443         unsigned int nofs_flag;
 444         char *name;
 445         int err = 0;
 446 
 447         /*
 448          * We're holding a transaction handle, so use a NOFS memory allocation
 449          * context to avoid deadlock if reclaim happens.
 450          */
 451         nofs_flag = memalloc_nofs_save();
 452         for (xattr = xattr_array; xattr->name != NULL; xattr++) {
 453                 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
 454                                strlen(xattr->name) + 1, GFP_KERNEL);
 455                 if (!name) {
 456                         err = -ENOMEM;
 457                         break;
 458                 }
 459                 strcpy(name, XATTR_SECURITY_PREFIX);
 460                 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
 461                 err = btrfs_setxattr(trans, inode, name, xattr->value,
 462                                      xattr->value_len, 0);
 463                 kfree(name);
 464                 if (err < 0)
 465                         break;
 466         }
 467         memalloc_nofs_restore(nofs_flag);
 468         return err;
 469 }
 470 
 471 int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
 472                               struct inode *inode, struct inode *dir,
 473                               const struct qstr *qstr)
 474 {
 475         return security_inode_init_security(inode, dir, qstr,
 476                                             &btrfs_initxattrs, trans);
 477 }

/* [<][>][^][v][top][bottom][index][help] */