LCOV - code coverage report
Current view: top level - fs/btrfs - xattr.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 188 214 87.9 %
Date: 2023-07-31 20:08:12 Functions: 8 8 100.0 %

          Line data    Source code
       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 "fs.h"
      17             : #include "messages.h"
      18             : #include "btrfs_inode.h"
      19             : #include "transaction.h"
      20             : #include "xattr.h"
      21             : #include "disk-io.h"
      22             : #include "props.h"
      23             : #include "locking.h"
      24             : #include "accessors.h"
      25             : #include "dir-item.h"
      26             : 
      27     2715182 : int btrfs_getxattr(struct inode *inode, const char *name,
      28             :                                 void *buffer, size_t size)
      29             : {
      30     2715182 :         struct btrfs_dir_item *di;
      31     2715182 :         struct btrfs_root *root = BTRFS_I(inode)->root;
      32     2715182 :         struct btrfs_path *path;
      33     2715182 :         struct extent_buffer *leaf;
      34     2715182 :         int ret = 0;
      35     2715182 :         unsigned long data_ptr;
      36             : 
      37     2715182 :         path = btrfs_alloc_path();
      38     2710644 :         if (!path)
      39             :                 return -ENOMEM;
      40             : 
      41             :         /* lookup the xattr by name */
      42     5421288 :         di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(BTRFS_I(inode)),
      43             :                         name, strlen(name), 0);
      44     2720776 :         if (!di) {
      45     2671826 :                 ret = -ENODATA;
      46     2671826 :                 goto out;
      47       48950 :         } else if (IS_ERR(di)) {
      48           0 :                 ret = PTR_ERR(di);
      49           0 :                 goto out;
      50             :         }
      51             : 
      52       48950 :         leaf = path->nodes[0];
      53             :         /* if size is 0, that means we want the size of the attr */
      54       48950 :         if (!size) {
      55       24629 :                 ret = btrfs_dir_data_len(leaf, di);
      56       24629 :                 goto out;
      57             :         }
      58             : 
      59             :         /* now get the data out of our dir_item */
      60       24321 :         if (btrfs_dir_data_len(leaf, di) > size) {
      61           0 :                 ret = -ERANGE;
      62           0 :                 goto out;
      63             :         }
      64             : 
      65             :         /*
      66             :          * The way things are packed into the leaf is like this
      67             :          * |struct btrfs_dir_item|name|data|
      68             :          * where name is the xattr name, so security.foo, and data is the
      69             :          * content of the xattr.  data_ptr points to the location in memory
      70             :          * where the data starts in the in memory leaf
      71             :          */
      72       24320 :         data_ptr = (unsigned long)((char *)(di + 1) +
      73       24320 :                                    btrfs_dir_name_len(leaf, di));
      74       24320 :         read_extent_buffer(leaf, buffer, data_ptr,
      75             :                            btrfs_dir_data_len(leaf, di));
      76       24320 :         ret = btrfs_dir_data_len(leaf, di);
      77             : 
      78     2720773 : out:
      79     2720773 :         btrfs_free_path(path);
      80     2720773 :         return ret;
      81             : }
      82             : 
      83     1437899 : int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
      84             :                    const char *name, const void *value, size_t size, int flags)
      85             : {
      86     1437899 :         struct btrfs_dir_item *di = NULL;
      87     1437899 :         struct btrfs_root *root = BTRFS_I(inode)->root;
      88     1437899 :         struct btrfs_fs_info *fs_info = root->fs_info;
      89     1437899 :         struct btrfs_path *path;
      90     1437899 :         size_t name_len = strlen(name);
      91     1437899 :         int ret = 0;
      92             : 
      93     1437899 :         ASSERT(trans);
      94             : 
      95     1437899 :         if (name_len + size > BTRFS_MAX_XATTR_SIZE(root->fs_info))
      96             :                 return -ENOSPC;
      97             : 
      98     1437835 :         path = btrfs_alloc_path();
      99     1437708 :         if (!path)
     100             :                 return -ENOMEM;
     101     1437708 :         path->skip_release_on_error = 1;
     102             : 
     103     1437708 :         if (!value) {
     104     1006468 :                 di = btrfs_lookup_xattr(trans, root, path,
     105             :                                 btrfs_ino(BTRFS_I(inode)), name, name_len, -1);
     106     1006941 :                 if (!di && (flags & XATTR_REPLACE))
     107             :                         ret = -ENODATA;
     108      976675 :                 else if (IS_ERR(di))
     109           0 :                         ret = PTR_ERR(di);
     110      976675 :                 else if (di)
     111       45544 :                         ret = btrfs_delete_one_dir_name(trans, root, path, di);
     112     1006940 :                 goto out;
     113             :         }
     114             : 
     115             :         /*
     116             :          * For a replace we can't just do the insert blindly.
     117             :          * Do a lookup first (read-only btrfs_search_slot), and return if xattr
     118             :          * doesn't exist. If it exists, fall down below to the insert/replace
     119             :          * path - we can't race with a concurrent xattr delete, because the VFS
     120             :          * locks the inode's i_mutex before calling setxattr or removexattr.
     121             :          */
     122      431240 :         if (flags & XATTR_REPLACE) {
     123       48056 :                 ASSERT(inode_is_locked(inode));
     124       48056 :                 di = btrfs_lookup_xattr(NULL, root, path,
     125             :                                 btrfs_ino(BTRFS_I(inode)), name, name_len, 0);
     126       48052 :                 if (!di)
     127             :                         ret = -ENODATA;
     128       28890 :                 else if (IS_ERR(di))
     129           0 :                         ret = PTR_ERR(di);
     130           0 :                 if (ret)
     131       19162 :                         goto out;
     132       28890 :                 btrfs_release_path(path);
     133       28890 :                 di = NULL;
     134             :         }
     135             : 
     136      412078 :         ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(BTRFS_I(inode)),
     137             :                                       name, name_len, value, size);
     138      412319 :         if (ret == -EOVERFLOW) {
     139             :                 /*
     140             :                  * We have an existing item in a leaf, split_leaf couldn't
     141             :                  * expand it. That item might have or not a dir_item that
     142             :                  * matches our target xattr, so lets check.
     143             :                  */
     144           0 :                 ret = 0;
     145           0 :                 btrfs_assert_tree_write_locked(path->nodes[0]);
     146           0 :                 di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
     147           0 :                 if (!di && !(flags & XATTR_REPLACE)) {
     148           0 :                         ret = -ENOSPC;
     149           0 :                         goto out;
     150             :                 }
     151      412319 :         } else if (ret == -EEXIST) {
     152       61464 :                 ret = 0;
     153       61464 :                 di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
     154       61464 :                 ASSERT(di); /* logic error */
     155      350855 :         } else if (ret) {
     156           0 :                 goto out;
     157             :         }
     158             : 
     159       61463 :         if (di && (flags & XATTR_CREATE)) {
     160         151 :                 ret = -EEXIST;
     161         151 :                 goto out;
     162             :         }
     163             : 
     164      412167 :         if (di) {
     165             :                 /*
     166             :                  * We're doing a replace, and it must be atomic, that is, at
     167             :                  * any point in time we have either the old or the new xattr
     168             :                  * value in the tree. We don't want readers (getxattr and
     169             :                  * listxattrs) to miss a value, this is specially important
     170             :                  * for ACLs.
     171             :                  */
     172       61312 :                 const int slot = path->slots[0];
     173       61312 :                 struct extent_buffer *leaf = path->nodes[0];
     174       61312 :                 const u16 old_data_len = btrfs_dir_data_len(leaf, di);
     175       61313 :                 const u32 item_size = btrfs_item_size(leaf, slot);
     176       61316 :                 const u32 data_size = sizeof(*di) + name_len + size;
     177       61316 :                 unsigned long data_ptr;
     178       61316 :                 char *ptr;
     179             : 
     180       61316 :                 if (size > old_data_len) {
     181       30144 :                         if (btrfs_leaf_free_space(leaf) <
     182       30143 :                             (size - old_data_len)) {
     183           0 :                                 ret = -ENOSPC;
     184           0 :                                 goto out;
     185             :                         }
     186             :                 }
     187             : 
     188       61315 :                 if (old_data_len + name_len + sizeof(*di) == item_size) {
     189             :                         /* No other xattrs packed in the same leaf item. */
     190       61315 :                         if (size > old_data_len)
     191       30143 :                                 btrfs_extend_item(path, size - old_data_len);
     192       31172 :                         else if (size < old_data_len)
     193       30520 :                                 btrfs_truncate_item(path, data_size, 1);
     194             :                 } else {
     195             :                         /* There are other xattrs packed in the same item. */
     196           0 :                         ret = btrfs_delete_one_dir_name(trans, root, path, di);
     197           0 :                         if (ret)
     198           0 :                                 goto out;
     199           0 :                         btrfs_extend_item(path, data_size);
     200             :                 }
     201             : 
     202       61313 :                 ptr = btrfs_item_ptr(leaf, slot, char);
     203       61312 :                 ptr += btrfs_item_size(leaf, slot) - data_size;
     204       61312 :                 di = (struct btrfs_dir_item *)ptr;
     205       61312 :                 btrfs_set_dir_data_len(leaf, di, size);
     206       61311 :                 data_ptr = ((unsigned long)(di + 1)) + name_len;
     207       61311 :                 write_extent_buffer(leaf, value, data_ptr, size);
     208       61309 :                 btrfs_mark_buffer_dirty(leaf);
     209             :         } else {
     210             :                 /*
     211             :                  * Insert, and we had space for the xattr, so path->slots[0] is
     212             :                  * where our xattr dir_item is and btrfs_insert_xattr_item()
     213             :                  * filled it.
     214             :                  */
     215     1438421 :         }
     216      350855 : out:
     217     1438421 :         btrfs_free_path(path);
     218     1438404 :         if (!ret) {
     219     1388838 :                 set_bit(BTRFS_INODE_COPY_EVERYTHING,
     220     1388838 :                         &BTRFS_I(inode)->runtime_flags);
     221     1388812 :                 clear_bit(BTRFS_INODE_NO_XATTRS, &BTRFS_I(inode)->runtime_flags);
     222             :         }
     223             :         return ret;
     224             : }
     225             : 
     226             : /*
     227             :  * @value: "" makes the attribute to empty, NULL removes it
     228             :  */
     229     1417319 : int btrfs_setxattr_trans(struct inode *inode, const char *name,
     230             :                          const void *value, size_t size, int flags)
     231             : {
     232     1417319 :         struct btrfs_root *root = BTRFS_I(inode)->root;
     233     1417319 :         struct btrfs_trans_handle *trans;
     234     1417319 :         const bool start_trans = (current->journal_info == NULL);
     235     1417319 :         int ret;
     236             : 
     237     1417319 :         if (start_trans) {
     238             :                 /*
     239             :                  * 1 unit for inserting/updating/deleting the xattr
     240             :                  * 1 unit for the inode item update
     241             :                  */
     242     1417319 :                 trans = btrfs_start_transaction(root, 2);
     243     1427451 :                 if (IS_ERR(trans))
     244       24143 :                         return PTR_ERR(trans);
     245             :         } else {
     246             :                 /*
     247             :                  * This can happen when smack is enabled and a directory is being
     248             :                  * created. It happens through d_instantiate_new(), which calls
     249             :                  * smack_d_instantiate(), which in turn calls __vfs_setxattr() to
     250             :                  * set the transmute xattr (XATTR_NAME_SMACKTRANSMUTE) on the
     251             :                  * inode. We have already reserved space for the xattr and inode
     252             :                  * update at btrfs_mkdir(), so just use the transaction handle.
     253             :                  * We don't join or start a transaction, as that will reset the
     254             :                  * block_rsv of the handle and trigger a warning for the start
     255             :                  * case.
     256             :                  */
     257           0 :                 ASSERT(strncmp(name, XATTR_SECURITY_PREFIX,
     258             :                                XATTR_SECURITY_PREFIX_LEN) == 0);
     259           0 :                 trans = current->journal_info;
     260             :         }
     261             : 
     262     1403308 :         ret = btrfs_setxattr(trans, inode, name, value, size, flags);
     263     1403653 :         if (ret)
     264       49644 :                 goto out;
     265             : 
     266     1354009 :         inode_inc_iversion(inode);
     267     1354001 :         inode->i_ctime = current_time(inode);
     268     1353842 :         ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
     269     1354041 :         if (ret)
     270           0 :                 btrfs_abort_transaction(trans, ret);
     271     1354041 : out:
     272     1403685 :         if (start_trans)
     273     1403648 :                 btrfs_end_transaction(trans);
     274             :         return ret;
     275             : }
     276             : 
     277      150167 : ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
     278             : {
     279      150167 :         struct btrfs_key found_key;
     280      150167 :         struct btrfs_key key;
     281      150167 :         struct inode *inode = d_inode(dentry);
     282      150167 :         struct btrfs_root *root = BTRFS_I(inode)->root;
     283      150167 :         struct btrfs_path *path;
     284      150167 :         int iter_ret = 0;
     285      150167 :         int ret = 0;
     286      150167 :         size_t total_size = 0, size_left = size;
     287             : 
     288             :         /*
     289             :          * ok we want all objects associated with this id.
     290             :          * NOTE: we set key.offset = 0; because we want to start with the
     291             :          * first xattr that we find and walk forward
     292             :          */
     293      150167 :         key.objectid = btrfs_ino(BTRFS_I(inode));
     294      150167 :         key.type = BTRFS_XATTR_ITEM_KEY;
     295      150167 :         key.offset = 0;
     296             : 
     297      150167 :         path = btrfs_alloc_path();
     298      150178 :         if (!path)
     299             :                 return -ENOMEM;
     300      150178 :         path->reada = READA_FORWARD;
     301             : 
     302             :         /* search for our xattrs */
     303      470258 :         btrfs_for_each_slot(root, &key, &found_key, path, iter_ret) {
     304      463157 :                 struct extent_buffer *leaf;
     305      463157 :                 int slot;
     306      463157 :                 struct btrfs_dir_item *di;
     307      463157 :                 u32 item_size;
     308      463157 :                 u32 cur;
     309             : 
     310      463157 :                 leaf = path->nodes[0];
     311      463157 :                 slot = path->slots[0];
     312             : 
     313             :                 /* check to make sure this item is what we want */
     314      463157 :                 if (found_key.objectid != key.objectid)
     315             :                         break;
     316      394969 :                 if (found_key.type > BTRFS_XATTR_ITEM_KEY)
     317             :                         break;
     318      320162 :                 if (found_key.type < BTRFS_XATTR_ITEM_KEY)
     319           0 :                         continue;
     320             : 
     321      320162 :                 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
     322      320107 :                 item_size = btrfs_item_size(leaf, slot);
     323      320107 :                 cur = 0;
     324      640262 :                 while (cur < item_size) {
     325      320206 :                         u16 name_len = btrfs_dir_name_len(leaf, di);
     326      320142 :                         u16 data_len = btrfs_dir_data_len(leaf, di);
     327      320174 :                         u32 this_len = sizeof(*di) + name_len + data_len;
     328      320174 :                         unsigned long name_ptr = (unsigned long)(di + 1);
     329             : 
     330      320174 :                         total_size += name_len + 1;
     331             :                         /*
     332             :                          * We are just looking for how big our buffer needs to
     333             :                          * be.
     334             :                          */
     335      320174 :                         if (!size)
     336       97683 :                                 goto next;
     337             : 
     338      222491 :                         if (!buffer || (name_len + 1) > size_left) {
     339             :                                 iter_ret = -ERANGE;
     340             :                                 break;
     341             :                         }
     342             : 
     343      222487 :                         read_extent_buffer(leaf, buffer, name_ptr, name_len);
     344      222472 :                         buffer[name_len] = '\0';
     345             : 
     346      222472 :                         size_left -= name_len + 1;
     347      222472 :                         buffer += name_len + 1;
     348      320155 : next:
     349      320155 :                         cur += this_len;
     350      320155 :                         di = (struct btrfs_dir_item *)((char *)di + this_len);
     351             :                 }
     352             :         }
     353             : 
     354      150191 :         if (iter_ret < 0)
     355             :                 ret = iter_ret;
     356             :         else
     357      150184 :                 ret = total_size;
     358             : 
     359      150191 :         btrfs_free_path(path);
     360             : 
     361      150192 :         return ret;
     362             : }
     363             : 
     364     2714351 : static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
     365             :                                    struct dentry *unused, struct inode *inode,
     366             :                                    const char *name, void *buffer, size_t size)
     367             : {
     368     2714351 :         name = xattr_full_name(handler, name);
     369     2709021 :         return btrfs_getxattr(inode, name, buffer, size);
     370             : }
     371             : 
     372      496184 : static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
     373             :                                    struct mnt_idmap *idmap,
     374             :                                    struct dentry *unused, struct inode *inode,
     375             :                                    const char *name, const void *buffer,
     376             :                                    size_t size, int flags)
     377             : {
     378      496184 :         if (btrfs_root_readonly(BTRFS_I(inode)->root))
     379             :                 return -EROFS;
     380             : 
     381      496180 :         name = xattr_full_name(handler, name);
     382      495830 :         return btrfs_setxattr_trans(inode, name, buffer, size, flags);
     383             : }
     384             : 
     385          40 : static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
     386             :                                         struct mnt_idmap *idmap,
     387             :                                         struct dentry *unused, struct inode *inode,
     388             :                                         const char *name, const void *value,
     389             :                                         size_t size, int flags)
     390             : {
     391          40 :         int ret;
     392          40 :         struct btrfs_trans_handle *trans;
     393          40 :         struct btrfs_root *root = BTRFS_I(inode)->root;
     394             : 
     395          40 :         name = xattr_full_name(handler, name);
     396          40 :         ret = btrfs_validate_prop(BTRFS_I(inode), name, value, size);
     397          40 :         if (ret)
     398             :                 return ret;
     399             : 
     400          26 :         if (btrfs_ignore_prop(BTRFS_I(inode), name))
     401             :                 return 0;
     402             : 
     403          26 :         trans = btrfs_start_transaction(root, 2);
     404          26 :         if (IS_ERR(trans))
     405           0 :                 return PTR_ERR(trans);
     406             : 
     407          26 :         ret = btrfs_set_prop(trans, inode, name, value, size, flags);
     408          26 :         if (!ret) {
     409          26 :                 inode_inc_iversion(inode);
     410          26 :                 inode->i_ctime = current_time(inode);
     411          26 :                 ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
     412          26 :                 if (ret)
     413           0 :                         btrfs_abort_transaction(trans, ret);
     414             :         }
     415             : 
     416          26 :         btrfs_end_transaction(trans);
     417             : 
     418          26 :         return ret;
     419             : }
     420             : 
     421             : static const struct xattr_handler btrfs_security_xattr_handler = {
     422             :         .prefix = XATTR_SECURITY_PREFIX,
     423             :         .get = btrfs_xattr_handler_get,
     424             :         .set = btrfs_xattr_handler_set,
     425             : };
     426             : 
     427             : static const struct xattr_handler btrfs_trusted_xattr_handler = {
     428             :         .prefix = XATTR_TRUSTED_PREFIX,
     429             :         .get = btrfs_xattr_handler_get,
     430             :         .set = btrfs_xattr_handler_set,
     431             : };
     432             : 
     433             : static const struct xattr_handler btrfs_user_xattr_handler = {
     434             :         .prefix = XATTR_USER_PREFIX,
     435             :         .get = btrfs_xattr_handler_get,
     436             :         .set = btrfs_xattr_handler_set,
     437             : };
     438             : 
     439             : static const struct xattr_handler btrfs_btrfs_xattr_handler = {
     440             :         .prefix = XATTR_BTRFS_PREFIX,
     441             :         .get = btrfs_xattr_handler_get,
     442             :         .set = btrfs_xattr_handler_set_prop,
     443             : };
     444             : 
     445             : const struct xattr_handler *btrfs_xattr_handlers[] = {
     446             :         &btrfs_security_xattr_handler,
     447             :         &btrfs_trusted_xattr_handler,
     448             :         &btrfs_user_xattr_handler,
     449             :         &btrfs_btrfs_xattr_handler,
     450             :         NULL,
     451             : };
     452             : 
     453             : static int btrfs_initxattrs(struct inode *inode,
     454             :                             const struct xattr *xattr_array, void *fs_private)
     455             : {
     456             :         struct btrfs_trans_handle *trans = fs_private;
     457             :         const struct xattr *xattr;
     458             :         unsigned int nofs_flag;
     459             :         char *name;
     460             :         int err = 0;
     461             : 
     462             :         /*
     463             :          * We're holding a transaction handle, so use a NOFS memory allocation
     464             :          * context to avoid deadlock if reclaim happens.
     465             :          */
     466             :         nofs_flag = memalloc_nofs_save();
     467             :         for (xattr = xattr_array; xattr->name != NULL; xattr++) {
     468             :                 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
     469             :                                strlen(xattr->name) + 1, GFP_KERNEL);
     470             :                 if (!name) {
     471             :                         err = -ENOMEM;
     472             :                         break;
     473             :                 }
     474             :                 strcpy(name, XATTR_SECURITY_PREFIX);
     475             :                 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
     476             :                 err = btrfs_setxattr(trans, inode, name, xattr->value,
     477             :                                      xattr->value_len, 0);
     478             :                 kfree(name);
     479             :                 if (err < 0)
     480             :                         break;
     481             :         }
     482             :         memalloc_nofs_restore(nofs_flag);
     483             :         return err;
     484             : }
     485             : 
     486     3266389 : int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
     487             :                               struct inode *inode, struct inode *dir,
     488             :                               const struct qstr *qstr)
     489             : {
     490     3266389 :         return security_inode_init_security(inode, dir, qstr,
     491             :                                             &btrfs_initxattrs, trans);
     492             : }

Generated by: LCOV version 1.14