hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/ecryptfs/inode.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /**
23 * eCryptfs: Linux filesystem encryption layer
34 *
....@@ -6,21 +7,6 @@
67 * Copyright (C) 2004-2007 International Business Machines Corp.
78 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
89 * Michael C. Thompsion <mcthomps@us.ibm.com>
9
- *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public License as
12
- * published by the Free Software Foundation; either version 2 of the
13
- * License, or (at your option) any later version.
14
- *
15
- * This program is distributed in the hope that it will be useful, but
16
- * WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
- * General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU General Public License
21
- * along with this program; if not, write to the Free Software
22
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23
- * 02111-1307, USA.
2410 */
2511
2612 #include <linux/file.h>
....@@ -142,13 +128,20 @@
142128 struct inode *inode)
143129 {
144130 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
145
- struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
146131 struct dentry *lower_dir_dentry;
132
+ struct inode *lower_dir_inode;
147133 int rc;
148134
149
- dget(lower_dentry);
150
- lower_dir_dentry = lock_parent(lower_dentry);
151
- rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
135
+ lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
136
+ lower_dir_inode = d_inode(lower_dir_dentry);
137
+ inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT);
138
+ dget(lower_dentry); // don't even try to make the lower negative
139
+ if (lower_dentry->d_parent != lower_dir_dentry)
140
+ rc = -EINVAL;
141
+ else if (d_unhashed(lower_dentry))
142
+ rc = -EINVAL;
143
+ else
144
+ rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
152145 if (rc) {
153146 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
154147 goto out_unlock;
....@@ -156,10 +149,11 @@
156149 fsstack_copy_attr_times(dir, lower_dir_inode);
157150 set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink);
158151 inode->i_ctime = dir->i_ctime;
159
- d_drop(dentry);
160152 out_unlock:
161
- unlock_dir(lower_dir_dentry);
162153 dput(lower_dentry);
154
+ inode_unlock(lower_dir_inode);
155
+ if (!rc)
156
+ d_drop(dentry);
163157 return rc;
164158 }
165159
....@@ -533,22 +527,30 @@
533527 {
534528 struct dentry *lower_dentry;
535529 struct dentry *lower_dir_dentry;
530
+ struct inode *lower_dir_inode;
536531 int rc;
537532
538533 lower_dentry = ecryptfs_dentry_to_lower(dentry);
539
- dget(dentry);
540
- lower_dir_dentry = lock_parent(lower_dentry);
541
- dget(lower_dentry);
542
- rc = vfs_rmdir(d_inode(lower_dir_dentry), lower_dentry);
543
- dput(lower_dentry);
544
- if (!rc && d_really_is_positive(dentry))
534
+ lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
535
+ lower_dir_inode = d_inode(lower_dir_dentry);
536
+
537
+ inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT);
538
+ dget(lower_dentry); // don't even try to make the lower negative
539
+ if (lower_dentry->d_parent != lower_dir_dentry)
540
+ rc = -EINVAL;
541
+ else if (d_unhashed(lower_dentry))
542
+ rc = -EINVAL;
543
+ else
544
+ rc = vfs_rmdir(lower_dir_inode, lower_dentry);
545
+ if (!rc) {
545546 clear_nlink(d_inode(dentry));
546
- fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
547
- set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink);
548
- unlock_dir(lower_dir_dentry);
547
+ fsstack_copy_attr_times(dir, lower_dir_inode);
548
+ set_nlink(dir, lower_dir_inode->i_nlink);
549
+ }
550
+ dput(lower_dentry);
551
+ inode_unlock(lower_dir_inode);
549552 if (!rc)
550553 d_drop(dentry);
551
- dput(dentry);
552554 return rc;
553555 }
554556
....@@ -586,25 +588,32 @@
586588 struct dentry *lower_new_dentry;
587589 struct dentry *lower_old_dir_dentry;
588590 struct dentry *lower_new_dir_dentry;
589
- struct dentry *trap = NULL;
591
+ struct dentry *trap;
590592 struct inode *target_inode;
591593
592594 if (flags)
593595 return -EINVAL;
594596
597
+ lower_old_dir_dentry = ecryptfs_dentry_to_lower(old_dentry->d_parent);
598
+ lower_new_dir_dentry = ecryptfs_dentry_to_lower(new_dentry->d_parent);
599
+
595600 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
596601 lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
597
- dget(lower_old_dentry);
598
- dget(lower_new_dentry);
599
- lower_old_dir_dentry = dget_parent(lower_old_dentry);
600
- lower_new_dir_dentry = dget_parent(lower_new_dentry);
602
+
601603 target_inode = d_inode(new_dentry);
604
+
602605 trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
603
- /* source should not be ancestor of target */
604
- if (trap == lower_old_dentry) {
605
- rc = -EINVAL;
606
+ dget(lower_new_dentry);
607
+ rc = -EINVAL;
608
+ if (lower_old_dentry->d_parent != lower_old_dir_dentry)
606609 goto out_lock;
607
- }
610
+ if (lower_new_dentry->d_parent != lower_new_dir_dentry)
611
+ goto out_lock;
612
+ if (d_unhashed(lower_old_dentry) || d_unhashed(lower_new_dentry))
613
+ goto out_lock;
614
+ /* source should not be ancestor of target */
615
+ if (trap == lower_old_dentry)
616
+ goto out_lock;
608617 /* target should not be ancestor of source */
609618 if (trap == lower_new_dentry) {
610619 rc = -ENOTEMPTY;
....@@ -622,11 +631,8 @@
622631 if (new_dir != old_dir)
623632 fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry));
624633 out_lock:
625
- unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
626
- dput(lower_new_dir_dentry);
627
- dput(lower_old_dir_dentry);
628634 dput(lower_new_dentry);
629
- dput(lower_old_dentry);
635
+ unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
630636 return rc;
631637 }
632638
....@@ -1034,7 +1040,8 @@
10341040 goto out;
10351041 }
10361042 inode_lock(lower_inode);
1037
- rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size);
1043
+ rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size,
1044
+ XATTR_NOSECURITY);
10381045 inode_unlock(lower_inode);
10391046 out:
10401047 return rc;
....@@ -1119,7 +1126,8 @@
11191126
11201127 static int ecryptfs_xattr_get(const struct xattr_handler *handler,
11211128 struct dentry *dentry, struct inode *inode,
1122
- const char *name, void *buffer, size_t size)
1129
+ const char *name, void *buffer, size_t size,
1130
+ int flags)
11231131 {
11241132 return ecryptfs_getxattr(dentry, inode, name, buffer, size);
11251133 }
....@@ -1137,7 +1145,7 @@
11371145 }
11381146 }
11391147
1140
-const struct xattr_handler ecryptfs_xattr_handler = {
1148
+static const struct xattr_handler ecryptfs_xattr_handler = {
11411149 .prefix = "", /* match anything */
11421150 .get = ecryptfs_xattr_get,
11431151 .set = ecryptfs_xattr_set,