aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2012-05-22 16:09:50 -0400
committerTyler Hicks <tyhicks@canonical.com>2012-07-08 13:51:44 -0400
commit8bc2d3cf612994a960c2e8eaea37f6676f67082a (patch)
tree88e1eb6d53540891b82d2a861146b213442de205 /fs
parent2ecaf55db6dcf4dd25e1ef8d5eb6068e3286a20f (diff)
eCryptfs: Unlink lower inode when ecryptfs_create() fails
ecryptfs_create() creates a lower inode, allocates an eCryptfs inode, initializes the eCryptfs inode and cryptographic metadata attached to the inode, and then writes the metadata to the header of the file. If an error was to occur after the lower inode was created, an empty lower file would be left in the lower filesystem. This is a problem because ecryptfs_open() refuses to open any lower files which do not have the appropriate metadata in the file header. This patch properly unlinks the lower inode when an error occurs in the later stages of ecryptfs_create(), reducing the chance that an empty lower file will be left in the lower filesystem. https://launchpad.net/bugs/872905 Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Cc: John Johansen <john.johansen@canonical.com> Cc: Colin Ian King <colin.king@canonical.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ecryptfs/inode.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index a07441a0a878..65efe5fa687c 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -143,6 +143,31 @@ static int ecryptfs_interpose(struct dentry *lower_dentry,
143 return 0; 143 return 0;
144} 144}
145 145
146static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
147 struct inode *inode)
148{
149 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
150 struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
151 struct dentry *lower_dir_dentry;
152 int rc;
153
154 dget(lower_dentry);
155 lower_dir_dentry = lock_parent(lower_dentry);
156 rc = vfs_unlink(lower_dir_inode, lower_dentry);
157 if (rc) {
158 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
159 goto out_unlock;
160 }
161 fsstack_copy_attr_times(dir, lower_dir_inode);
162 set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink);
163 inode->i_ctime = dir->i_ctime;
164 d_drop(dentry);
165out_unlock:
166 unlock_dir(lower_dir_dentry);
167 dput(lower_dentry);
168 return rc;
169}
170
146/** 171/**
147 * ecryptfs_do_create 172 * ecryptfs_do_create
148 * @directory_inode: inode of the new file's dentry's parent in ecryptfs 173 * @directory_inode: inode of the new file's dentry's parent in ecryptfs
@@ -182,8 +207,10 @@ ecryptfs_do_create(struct inode *directory_inode,
182 } 207 }
183 inode = __ecryptfs_get_inode(lower_dentry->d_inode, 208 inode = __ecryptfs_get_inode(lower_dentry->d_inode,
184 directory_inode->i_sb); 209 directory_inode->i_sb);
185 if (IS_ERR(inode)) 210 if (IS_ERR(inode)) {
211 vfs_unlink(lower_dir_dentry->d_inode, lower_dentry);
186 goto out_lock; 212 goto out_lock;
213 }
187 fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); 214 fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode);
188 fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); 215 fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode);
189out_lock: 216out_lock:
@@ -265,7 +292,9 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
265 * that this on disk file is prepared to be an ecryptfs file */ 292 * that this on disk file is prepared to be an ecryptfs file */
266 rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); 293 rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode);
267 if (rc) { 294 if (rc) {
268 drop_nlink(ecryptfs_inode); 295 ecryptfs_do_unlink(directory_inode, ecryptfs_dentry,
296 ecryptfs_inode);
297 make_bad_inode(ecryptfs_inode);
269 unlock_new_inode(ecryptfs_inode); 298 unlock_new_inode(ecryptfs_inode);
270 iput(ecryptfs_inode); 299 iput(ecryptfs_inode);
271 goto out; 300 goto out;
@@ -477,27 +506,7 @@ out_lock:
477 506
478static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) 507static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
479{ 508{
480 int rc = 0; 509 return ecryptfs_do_unlink(dir, dentry, dentry->d_inode);
481 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
482 struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
483 struct dentry *lower_dir_dentry;
484
485 dget(lower_dentry);
486 lower_dir_dentry = lock_parent(lower_dentry);
487 rc = vfs_unlink(lower_dir_inode, lower_dentry);
488 if (rc) {
489 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
490 goto out_unlock;
491 }
492 fsstack_copy_attr_times(dir, lower_dir_inode);
493 set_nlink(dentry->d_inode,
494 ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink);
495 dentry->d_inode->i_ctime = dir->i_ctime;
496 d_drop(dentry);
497out_unlock:
498 unlock_dir(lower_dir_dentry);
499 dput(lower_dentry);
500 return rc;
501} 510}
502 511
503static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, 512static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,