| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* * This file is part of UBIFS. |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2006-2008 Nokia Corporation. |
|---|
| 4 | 5 | * Copyright (C) 2006, 2007 University of Szeged, Hungary |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 8 | | - * the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 16 | | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
|---|
| 17 | | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 18 | 6 | * |
|---|
| 19 | 7 | * Authors: Artem Bityutskiy (Битюцкий Артём) |
|---|
| 20 | 8 | * Adrian Hunter |
|---|
| .. | .. |
|---|
| 93 | 81 | struct ubifs_inode *ui; |
|---|
| 94 | 82 | bool encrypted = false; |
|---|
| 95 | 83 | |
|---|
| 96 | | - if (ubifs_crypt_is_encrypted(dir)) { |
|---|
| 97 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 98 | | - if (err) { |
|---|
| 99 | | - ubifs_err(c, "fscrypt_get_encryption_info failed: %i", err); |
|---|
| 100 | | - return ERR_PTR(err); |
|---|
| 101 | | - } |
|---|
| 102 | | - |
|---|
| 103 | | - if (!fscrypt_has_encryption_key(dir)) |
|---|
| 104 | | - return ERR_PTR(-EPERM); |
|---|
| 105 | | - |
|---|
| 106 | | - encrypted = true; |
|---|
| 107 | | - } |
|---|
| 108 | | - |
|---|
| 109 | 84 | inode = new_inode(c->vfs_sb); |
|---|
| 110 | 85 | ui = ubifs_inode(inode); |
|---|
| 111 | 86 | if (!inode) |
|---|
| .. | .. |
|---|
| 123 | 98 | inode->i_mtime = inode->i_atime = inode->i_ctime = |
|---|
| 124 | 99 | current_time(inode); |
|---|
| 125 | 100 | inode->i_mapping->nrpages = 0; |
|---|
| 101 | + |
|---|
| 102 | + err = fscrypt_prepare_new_inode(dir, inode, &encrypted); |
|---|
| 103 | + if (err) { |
|---|
| 104 | + ubifs_err(c, "fscrypt_prepare_new_inode failed: %i", err); |
|---|
| 105 | + goto out_iput; |
|---|
| 106 | + } |
|---|
| 126 | 107 | |
|---|
| 127 | 108 | switch (mode & S_IFMT) { |
|---|
| 128 | 109 | case S_IFREG: |
|---|
| .. | .. |
|---|
| 143 | 124 | case S_IFBLK: |
|---|
| 144 | 125 | case S_IFCHR: |
|---|
| 145 | 126 | inode->i_op = &ubifs_file_inode_operations; |
|---|
| 146 | | - encrypted = false; |
|---|
| 147 | 127 | break; |
|---|
| 148 | 128 | default: |
|---|
| 149 | 129 | BUG(); |
|---|
| .. | .. |
|---|
| 163 | 143 | if (c->highest_inum >= INUM_WATERMARK) { |
|---|
| 164 | 144 | spin_unlock(&c->cnt_lock); |
|---|
| 165 | 145 | ubifs_err(c, "out of inode numbers"); |
|---|
| 166 | | - make_bad_inode(inode); |
|---|
| 167 | | - iput(inode); |
|---|
| 168 | | - return ERR_PTR(-EINVAL); |
|---|
| 146 | + err = -EINVAL; |
|---|
| 147 | + goto out_iput; |
|---|
| 169 | 148 | } |
|---|
| 170 | 149 | ubifs_warn(c, "running out of inode numbers (current %lu, max %u)", |
|---|
| 171 | 150 | (unsigned long)c->highest_inum, INUM_WATERMARK); |
|---|
| .. | .. |
|---|
| 183 | 162 | spin_unlock(&c->cnt_lock); |
|---|
| 184 | 163 | |
|---|
| 185 | 164 | if (encrypted) { |
|---|
| 186 | | - err = fscrypt_inherit_context(dir, inode, &encrypted, true); |
|---|
| 165 | + err = fscrypt_set_context(inode, NULL); |
|---|
| 187 | 166 | if (err) { |
|---|
| 188 | | - ubifs_err(c, "fscrypt_inherit_context failed: %i", err); |
|---|
| 189 | | - make_bad_inode(inode); |
|---|
| 190 | | - iput(inode); |
|---|
| 191 | | - return ERR_PTR(err); |
|---|
| 167 | + ubifs_err(c, "fscrypt_set_context failed: %i", err); |
|---|
| 168 | + goto out_iput; |
|---|
| 192 | 169 | } |
|---|
| 193 | 170 | } |
|---|
| 194 | 171 | |
|---|
| 195 | 172 | return inode; |
|---|
| 173 | + |
|---|
| 174 | +out_iput: |
|---|
| 175 | + make_bad_inode(inode); |
|---|
| 176 | + iput(inode); |
|---|
| 177 | + return ERR_PTR(err); |
|---|
| 196 | 178 | } |
|---|
| 197 | 179 | |
|---|
| 198 | 180 | static int dbg_check_name(const struct ubifs_info *c, |
|---|
| .. | .. |
|---|
| 208 | 190 | return 0; |
|---|
| 209 | 191 | } |
|---|
| 210 | 192 | |
|---|
| 211 | | -static void ubifs_set_d_ops(struct inode *dir, struct dentry *dentry); |
|---|
| 212 | 193 | static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, |
|---|
| 213 | 194 | unsigned int flags) |
|---|
| 214 | 195 | { |
|---|
| .. | .. |
|---|
| 222 | 203 | dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino); |
|---|
| 223 | 204 | |
|---|
| 224 | 205 | err = fscrypt_prepare_lookup(dir, dentry, &nm); |
|---|
| 225 | | - ubifs_set_d_ops(dir, dentry); |
|---|
| 206 | + generic_set_encrypted_ci_d_ops(dentry); |
|---|
| 226 | 207 | if (err == -ENOENT) |
|---|
| 227 | 208 | return d_splice_alias(NULL, dentry); |
|---|
| 228 | 209 | if (err) |
|---|
| .. | .. |
|---|
| 275 | 256 | goto done; |
|---|
| 276 | 257 | } |
|---|
| 277 | 258 | |
|---|
| 278 | | - if (ubifs_crypt_is_encrypted(dir) && |
|---|
| 259 | + if (IS_ENCRYPTED(dir) && |
|---|
| 279 | 260 | (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && |
|---|
| 280 | 261 | !fscrypt_has_permitted_context(dir, inode)) { |
|---|
| 281 | 262 | ubifs_warn(c, "Inconsistent encryption contexts: %lu/%lu", |
|---|
| .. | .. |
|---|
| 373 | 354 | { |
|---|
| 374 | 355 | struct inode *inode; |
|---|
| 375 | 356 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
|---|
| 376 | | - struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1}; |
|---|
| 357 | + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
|---|
| 358 | + .dirtied_ino = 1}; |
|---|
| 377 | 359 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1 }; |
|---|
| 378 | 360 | struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir); |
|---|
| 379 | 361 | int err, instantiated = 0; |
|---|
| 380 | 362 | struct fscrypt_name nm; |
|---|
| 381 | 363 | |
|---|
| 382 | 364 | /* |
|---|
| 383 | | - * Budget request settings: new dirty inode, new direntry, |
|---|
| 384 | | - * budget for dirtied inode will be released via writeback. |
|---|
| 365 | + * Budget request settings: new inode, new direntry, changing the |
|---|
| 366 | + * parent directory inode. |
|---|
| 367 | + * Allocate budget separately for new dirtied inode, the budget will |
|---|
| 368 | + * be released via writeback. |
|---|
| 385 | 369 | */ |
|---|
| 386 | 370 | |
|---|
| 387 | 371 | dbg_gen("dent '%pd', mode %#hx in dir ino %lu", |
|---|
| .. | .. |
|---|
| 451 | 435 | make_bad_inode(inode); |
|---|
| 452 | 436 | if (!instantiated) |
|---|
| 453 | 437 | iput(inode); |
|---|
| 438 | + else if (whiteout) |
|---|
| 439 | + iput(*whiteout); |
|---|
| 454 | 440 | out_budg: |
|---|
| 455 | 441 | ubifs_release_budget(c, &req); |
|---|
| 456 | 442 | if (!instantiated) |
|---|
| .. | .. |
|---|
| 522 | 508 | struct ubifs_dent_node *dent; |
|---|
| 523 | 509 | struct inode *dir = file_inode(file); |
|---|
| 524 | 510 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
|---|
| 525 | | - bool encrypted = ubifs_crypt_is_encrypted(dir); |
|---|
| 511 | + bool encrypted = IS_ENCRYPTED(dir); |
|---|
| 526 | 512 | |
|---|
| 527 | 513 | dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos); |
|---|
| 528 | 514 | |
|---|
| .. | .. |
|---|
| 534 | 520 | return 0; |
|---|
| 535 | 521 | |
|---|
| 536 | 522 | if (encrypted) { |
|---|
| 537 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 523 | + err = fscrypt_prepare_readdir(dir); |
|---|
| 538 | 524 | if (err) |
|---|
| 539 | 525 | return err; |
|---|
| 540 | 526 | |
|---|
| 541 | | - err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, &fstr); |
|---|
| 527 | + err = fscrypt_fname_alloc_buffer(UBIFS_MAX_NLEN, &fstr); |
|---|
| 542 | 528 | if (err) |
|---|
| 543 | 529 | return err; |
|---|
| 544 | 530 | |
|---|
| .. | .. |
|---|
| 801 | 787 | dentry, inode->i_ino, |
|---|
| 802 | 788 | inode->i_nlink, dir->i_ino); |
|---|
| 803 | 789 | |
|---|
| 804 | | - if (ubifs_crypt_is_encrypted(dir)) { |
|---|
| 805 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 806 | | - if (err && err != -ENOKEY) |
|---|
| 807 | | - return err; |
|---|
| 808 | | - } |
|---|
| 809 | | - |
|---|
| 810 | 790 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); |
|---|
| 791 | + if (err) |
|---|
| 792 | + return err; |
|---|
| 793 | + |
|---|
| 794 | + err = ubifs_purge_xattrs(inode); |
|---|
| 811 | 795 | if (err) |
|---|
| 812 | 796 | return err; |
|---|
| 813 | 797 | |
|---|
| .. | .. |
|---|
| 911 | 895 | if (err) |
|---|
| 912 | 896 | return err; |
|---|
| 913 | 897 | |
|---|
| 914 | | - if (ubifs_crypt_is_encrypted(dir)) { |
|---|
| 915 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 916 | | - if (err && err != -ENOKEY) |
|---|
| 917 | | - return err; |
|---|
| 918 | | - } |
|---|
| 919 | | - |
|---|
| 920 | 898 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); |
|---|
| 899 | + if (err) |
|---|
| 900 | + return err; |
|---|
| 901 | + |
|---|
| 902 | + err = ubifs_purge_xattrs(inode); |
|---|
| 921 | 903 | if (err) |
|---|
| 922 | 904 | return err; |
|---|
| 923 | 905 | |
|---|
| .. | .. |
|---|
| 971 | 953 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
|---|
| 972 | 954 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
|---|
| 973 | 955 | int err, sz_change; |
|---|
| 974 | | - struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 }; |
|---|
| 956 | + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
|---|
| 957 | + .dirtied_ino = 1}; |
|---|
| 975 | 958 | struct fscrypt_name nm; |
|---|
| 976 | 959 | |
|---|
| 977 | 960 | /* |
|---|
| .. | .. |
|---|
| 1287 | 1270 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1, |
|---|
| 1288 | 1271 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
|---|
| 1289 | 1272 | struct timespec64 time; |
|---|
| 1290 | | - unsigned int uninitialized_var(saved_nlink); |
|---|
| 1273 | + unsigned int saved_nlink; |
|---|
| 1291 | 1274 | struct fscrypt_name old_nm, new_nm; |
|---|
| 1292 | 1275 | |
|---|
| 1293 | 1276 | /* |
|---|
| .. | .. |
|---|
| 1303 | 1286 | old_dentry, old_inode->i_ino, old_dir->i_ino, |
|---|
| 1304 | 1287 | new_dentry, new_dir->i_ino, flags); |
|---|
| 1305 | 1288 | |
|---|
| 1306 | | - if (unlink) |
|---|
| 1289 | + if (unlink) { |
|---|
| 1307 | 1290 | ubifs_assert(c, inode_is_locked(new_inode)); |
|---|
| 1291 | + |
|---|
| 1292 | + err = ubifs_purge_xattrs(new_inode); |
|---|
| 1293 | + if (err) |
|---|
| 1294 | + return err; |
|---|
| 1295 | + } |
|---|
| 1308 | 1296 | |
|---|
| 1309 | 1297 | if (unlink && is_dir) { |
|---|
| 1310 | 1298 | err = ubifs_check_dir_empty(new_inode); |
|---|
| .. | .. |
|---|
| 1341 | 1329 | |
|---|
| 1342 | 1330 | if (flags & RENAME_WHITEOUT) { |
|---|
| 1343 | 1331 | union ubifs_dev_desc *dev = NULL; |
|---|
| 1332 | + struct ubifs_budget_req wht_req; |
|---|
| 1344 | 1333 | |
|---|
| 1345 | 1334 | dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); |
|---|
| 1346 | 1335 | if (!dev) { |
|---|
| .. | .. |
|---|
| 1362 | 1351 | whiteout_ui->data = dev; |
|---|
| 1363 | 1352 | whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0)); |
|---|
| 1364 | 1353 | ubifs_assert(c, !whiteout_ui->dirty); |
|---|
| 1354 | + |
|---|
| 1355 | + memset(&wht_req, 0, sizeof(struct ubifs_budget_req)); |
|---|
| 1356 | + wht_req.dirtied_ino = 1; |
|---|
| 1357 | + wht_req.dirtied_ino_d = ALIGN(whiteout_ui->data_len, 8); |
|---|
| 1358 | + /* |
|---|
| 1359 | + * To avoid deadlock between space budget (holds ui_mutex and |
|---|
| 1360 | + * waits wb work) and writeback work(waits ui_mutex), do space |
|---|
| 1361 | + * budget before ubifs inodes locked. |
|---|
| 1362 | + */ |
|---|
| 1363 | + err = ubifs_budget_space(c, &wht_req); |
|---|
| 1364 | + if (err) { |
|---|
| 1365 | + iput(whiteout); |
|---|
| 1366 | + goto out_release; |
|---|
| 1367 | + } |
|---|
| 1368 | + |
|---|
| 1369 | + /* Add the old_dentry size to the old_dir size. */ |
|---|
| 1370 | + old_sz -= CALC_DENT_SIZE(fname_len(&old_nm)); |
|---|
| 1365 | 1371 | } |
|---|
| 1366 | 1372 | |
|---|
| 1367 | 1373 | lock_4_inodes(old_dir, new_dir, new_inode, whiteout); |
|---|
| .. | .. |
|---|
| 1436 | 1442 | } |
|---|
| 1437 | 1443 | |
|---|
| 1438 | 1444 | if (whiteout) { |
|---|
| 1439 | | - struct ubifs_budget_req wht_req = { .dirtied_ino = 1, |
|---|
| 1440 | | - .dirtied_ino_d = \ |
|---|
| 1441 | | - ALIGN(ubifs_inode(whiteout)->data_len, 8) }; |
|---|
| 1442 | | - |
|---|
| 1443 | | - err = ubifs_budget_space(c, &wht_req); |
|---|
| 1444 | | - if (err) { |
|---|
| 1445 | | - kfree(whiteout_ui->data); |
|---|
| 1446 | | - whiteout_ui->data_len = 0; |
|---|
| 1447 | | - iput(whiteout); |
|---|
| 1448 | | - goto out_release; |
|---|
| 1449 | | - } |
|---|
| 1450 | | - |
|---|
| 1451 | 1445 | inc_nlink(whiteout); |
|---|
| 1452 | 1446 | mark_inode_dirty(whiteout); |
|---|
| 1453 | 1447 | |
|---|
| .. | .. |
|---|
| 1645 | 1639 | return 0; |
|---|
| 1646 | 1640 | } |
|---|
| 1647 | 1641 | |
|---|
| 1648 | | -static int ubifs_dir_open(struct inode *dir, struct file *file) |
|---|
| 1649 | | -{ |
|---|
| 1650 | | - if (ubifs_crypt_is_encrypted(dir)) |
|---|
| 1651 | | - return fscrypt_get_encryption_info(dir) ? -EACCES : 0; |
|---|
| 1652 | | - |
|---|
| 1653 | | - return 0; |
|---|
| 1654 | | -} |
|---|
| 1655 | | - |
|---|
| 1656 | 1642 | const struct inode_operations ubifs_dir_inode_operations = { |
|---|
| 1657 | 1643 | .lookup = ubifs_lookup, |
|---|
| 1658 | 1644 | .create = ubifs_create, |
|---|
| .. | .. |
|---|
| 1668 | 1654 | #ifdef CONFIG_UBIFS_FS_XATTR |
|---|
| 1669 | 1655 | .listxattr = ubifs_listxattr, |
|---|
| 1670 | 1656 | #endif |
|---|
| 1671 | | -#ifdef CONFIG_UBIFS_ATIME_SUPPORT |
|---|
| 1672 | 1657 | .update_time = ubifs_update_time, |
|---|
| 1673 | | -#endif |
|---|
| 1674 | 1658 | .tmpfile = ubifs_tmpfile, |
|---|
| 1675 | 1659 | }; |
|---|
| 1676 | 1660 | |
|---|
| .. | .. |
|---|
| 1681 | 1665 | .iterate_shared = ubifs_readdir, |
|---|
| 1682 | 1666 | .fsync = ubifs_fsync, |
|---|
| 1683 | 1667 | .unlocked_ioctl = ubifs_ioctl, |
|---|
| 1684 | | - .open = ubifs_dir_open, |
|---|
| 1685 | 1668 | #ifdef CONFIG_COMPAT |
|---|
| 1686 | 1669 | .compat_ioctl = ubifs_compat_ioctl, |
|---|
| 1687 | 1670 | #endif |
|---|
| 1688 | 1671 | }; |
|---|
| 1689 | | - |
|---|
| 1690 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 1691 | | -static const struct dentry_operations ubifs_encrypted_dentry_ops = { |
|---|
| 1692 | | - .d_revalidate = fscrypt_d_revalidate, |
|---|
| 1693 | | -}; |
|---|
| 1694 | | -#endif |
|---|
| 1695 | | - |
|---|
| 1696 | | -static void ubifs_set_d_ops(struct inode *dir, struct dentry *dentry) |
|---|
| 1697 | | -{ |
|---|
| 1698 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 1699 | | - if (dentry->d_flags & DCACHE_ENCRYPTED_NAME) { |
|---|
| 1700 | | - d_set_d_op(dentry, &ubifs_encrypted_dentry_ops); |
|---|
| 1701 | | - return; |
|---|
| 1702 | | - } |
|---|
| 1703 | | -#endif |
|---|
| 1704 | | -} |
|---|