1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /**
3*4882a593Smuzhiyun * eCryptfs: Linux filesystem encryption layer
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 1997-2004 Erez Zadok
6*4882a593Smuzhiyun * Copyright (C) 2001-2004 Stony Brook University
7*4882a593Smuzhiyun * Copyright (C) 2004-2007 International Business Machines Corp.
8*4882a593Smuzhiyun * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
9*4882a593Smuzhiyun * Michael C. Thompsion <mcthomps@us.ibm.com>
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/file.h>
13*4882a593Smuzhiyun #include <linux/vmalloc.h>
14*4882a593Smuzhiyun #include <linux/pagemap.h>
15*4882a593Smuzhiyun #include <linux/dcache.h>
16*4882a593Smuzhiyun #include <linux/namei.h>
17*4882a593Smuzhiyun #include <linux/mount.h>
18*4882a593Smuzhiyun #include <linux/fs_stack.h>
19*4882a593Smuzhiyun #include <linux/slab.h>
20*4882a593Smuzhiyun #include <linux/xattr.h>
21*4882a593Smuzhiyun #include <asm/unaligned.h>
22*4882a593Smuzhiyun #include "ecryptfs_kernel.h"
23*4882a593Smuzhiyun
lock_parent(struct dentry * dentry)24*4882a593Smuzhiyun static struct dentry *lock_parent(struct dentry *dentry)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun struct dentry *dir;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun dir = dget_parent(dentry);
29*4882a593Smuzhiyun inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
30*4882a593Smuzhiyun return dir;
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun
unlock_dir(struct dentry * dir)33*4882a593Smuzhiyun static void unlock_dir(struct dentry *dir)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun inode_unlock(d_inode(dir));
36*4882a593Smuzhiyun dput(dir);
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun
ecryptfs_inode_test(struct inode * inode,void * lower_inode)39*4882a593Smuzhiyun static int ecryptfs_inode_test(struct inode *inode, void *lower_inode)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun return ecryptfs_inode_to_lower(inode) == lower_inode;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun
ecryptfs_inode_set(struct inode * inode,void * opaque)44*4882a593Smuzhiyun static int ecryptfs_inode_set(struct inode *inode, void *opaque)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun struct inode *lower_inode = opaque;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun ecryptfs_set_inode_lower(inode, lower_inode);
49*4882a593Smuzhiyun fsstack_copy_attr_all(inode, lower_inode);
50*4882a593Smuzhiyun /* i_size will be overwritten for encrypted regular files */
51*4882a593Smuzhiyun fsstack_copy_inode_size(inode, lower_inode);
52*4882a593Smuzhiyun inode->i_ino = lower_inode->i_ino;
53*4882a593Smuzhiyun inode->i_mapping->a_ops = &ecryptfs_aops;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun if (S_ISLNK(inode->i_mode))
56*4882a593Smuzhiyun inode->i_op = &ecryptfs_symlink_iops;
57*4882a593Smuzhiyun else if (S_ISDIR(inode->i_mode))
58*4882a593Smuzhiyun inode->i_op = &ecryptfs_dir_iops;
59*4882a593Smuzhiyun else
60*4882a593Smuzhiyun inode->i_op = &ecryptfs_main_iops;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun if (S_ISDIR(inode->i_mode))
63*4882a593Smuzhiyun inode->i_fop = &ecryptfs_dir_fops;
64*4882a593Smuzhiyun else if (special_file(inode->i_mode))
65*4882a593Smuzhiyun init_special_inode(inode, inode->i_mode, inode->i_rdev);
66*4882a593Smuzhiyun else
67*4882a593Smuzhiyun inode->i_fop = &ecryptfs_main_fops;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun return 0;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
__ecryptfs_get_inode(struct inode * lower_inode,struct super_block * sb)72*4882a593Smuzhiyun static struct inode *__ecryptfs_get_inode(struct inode *lower_inode,
73*4882a593Smuzhiyun struct super_block *sb)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun struct inode *inode;
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb))
78*4882a593Smuzhiyun return ERR_PTR(-EXDEV);
79*4882a593Smuzhiyun if (!igrab(lower_inode))
80*4882a593Smuzhiyun return ERR_PTR(-ESTALE);
81*4882a593Smuzhiyun inode = iget5_locked(sb, (unsigned long)lower_inode,
82*4882a593Smuzhiyun ecryptfs_inode_test, ecryptfs_inode_set,
83*4882a593Smuzhiyun lower_inode);
84*4882a593Smuzhiyun if (!inode) {
85*4882a593Smuzhiyun iput(lower_inode);
86*4882a593Smuzhiyun return ERR_PTR(-EACCES);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun if (!(inode->i_state & I_NEW))
89*4882a593Smuzhiyun iput(lower_inode);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun return inode;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun
ecryptfs_get_inode(struct inode * lower_inode,struct super_block * sb)94*4882a593Smuzhiyun struct inode *ecryptfs_get_inode(struct inode *lower_inode,
95*4882a593Smuzhiyun struct super_block *sb)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun struct inode *inode = __ecryptfs_get_inode(lower_inode, sb);
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun if (!IS_ERR(inode) && (inode->i_state & I_NEW))
100*4882a593Smuzhiyun unlock_new_inode(inode);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun return inode;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /**
106*4882a593Smuzhiyun * ecryptfs_interpose
107*4882a593Smuzhiyun * @lower_dentry: Existing dentry in the lower filesystem
108*4882a593Smuzhiyun * @dentry: ecryptfs' dentry
109*4882a593Smuzhiyun * @sb: ecryptfs's super_block
110*4882a593Smuzhiyun *
111*4882a593Smuzhiyun * Interposes upper and lower dentries.
112*4882a593Smuzhiyun *
113*4882a593Smuzhiyun * Returns zero on success; non-zero otherwise
114*4882a593Smuzhiyun */
ecryptfs_interpose(struct dentry * lower_dentry,struct dentry * dentry,struct super_block * sb)115*4882a593Smuzhiyun static int ecryptfs_interpose(struct dentry *lower_dentry,
116*4882a593Smuzhiyun struct dentry *dentry, struct super_block *sb)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun struct inode *inode = ecryptfs_get_inode(d_inode(lower_dentry), sb);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun if (IS_ERR(inode))
121*4882a593Smuzhiyun return PTR_ERR(inode);
122*4882a593Smuzhiyun d_instantiate(dentry, inode);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun return 0;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
ecryptfs_do_unlink(struct inode * dir,struct dentry * dentry,struct inode * inode)127*4882a593Smuzhiyun static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
128*4882a593Smuzhiyun struct inode *inode)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
131*4882a593Smuzhiyun struct dentry *lower_dir_dentry;
132*4882a593Smuzhiyun struct inode *lower_dir_inode;
133*4882a593Smuzhiyun int rc;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
136*4882a593Smuzhiyun lower_dir_inode = d_inode(lower_dir_dentry);
137*4882a593Smuzhiyun inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT);
138*4882a593Smuzhiyun dget(lower_dentry); // don't even try to make the lower negative
139*4882a593Smuzhiyun if (lower_dentry->d_parent != lower_dir_dentry)
140*4882a593Smuzhiyun rc = -EINVAL;
141*4882a593Smuzhiyun else if (d_unhashed(lower_dentry))
142*4882a593Smuzhiyun rc = -EINVAL;
143*4882a593Smuzhiyun else
144*4882a593Smuzhiyun rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
145*4882a593Smuzhiyun if (rc) {
146*4882a593Smuzhiyun printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
147*4882a593Smuzhiyun goto out_unlock;
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun fsstack_copy_attr_times(dir, lower_dir_inode);
150*4882a593Smuzhiyun set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink);
151*4882a593Smuzhiyun inode->i_ctime = dir->i_ctime;
152*4882a593Smuzhiyun out_unlock:
153*4882a593Smuzhiyun dput(lower_dentry);
154*4882a593Smuzhiyun inode_unlock(lower_dir_inode);
155*4882a593Smuzhiyun if (!rc)
156*4882a593Smuzhiyun d_drop(dentry);
157*4882a593Smuzhiyun return rc;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun /**
161*4882a593Smuzhiyun * ecryptfs_do_create
162*4882a593Smuzhiyun * @directory_inode: inode of the new file's dentry's parent in ecryptfs
163*4882a593Smuzhiyun * @ecryptfs_dentry: New file's dentry in ecryptfs
164*4882a593Smuzhiyun * @mode: The mode of the new file
165*4882a593Smuzhiyun *
166*4882a593Smuzhiyun * Creates the underlying file and the eCryptfs inode which will link to
167*4882a593Smuzhiyun * it. It will also update the eCryptfs directory inode to mimic the
168*4882a593Smuzhiyun * stat of the lower directory inode.
169*4882a593Smuzhiyun *
170*4882a593Smuzhiyun * Returns the new eCryptfs inode on success; an ERR_PTR on error condition
171*4882a593Smuzhiyun */
172*4882a593Smuzhiyun static struct inode *
ecryptfs_do_create(struct inode * directory_inode,struct dentry * ecryptfs_dentry,umode_t mode)173*4882a593Smuzhiyun ecryptfs_do_create(struct inode *directory_inode,
174*4882a593Smuzhiyun struct dentry *ecryptfs_dentry, umode_t mode)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun int rc;
177*4882a593Smuzhiyun struct dentry *lower_dentry;
178*4882a593Smuzhiyun struct dentry *lower_dir_dentry;
179*4882a593Smuzhiyun struct inode *inode;
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
182*4882a593Smuzhiyun lower_dir_dentry = lock_parent(lower_dentry);
183*4882a593Smuzhiyun rc = vfs_create(d_inode(lower_dir_dentry), lower_dentry, mode, true);
184*4882a593Smuzhiyun if (rc) {
185*4882a593Smuzhiyun printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
186*4882a593Smuzhiyun "rc = [%d]\n", __func__, rc);
187*4882a593Smuzhiyun inode = ERR_PTR(rc);
188*4882a593Smuzhiyun goto out_lock;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun inode = __ecryptfs_get_inode(d_inode(lower_dentry),
191*4882a593Smuzhiyun directory_inode->i_sb);
192*4882a593Smuzhiyun if (IS_ERR(inode)) {
193*4882a593Smuzhiyun vfs_unlink(d_inode(lower_dir_dentry), lower_dentry, NULL);
194*4882a593Smuzhiyun goto out_lock;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun fsstack_copy_attr_times(directory_inode, d_inode(lower_dir_dentry));
197*4882a593Smuzhiyun fsstack_copy_inode_size(directory_inode, d_inode(lower_dir_dentry));
198*4882a593Smuzhiyun out_lock:
199*4882a593Smuzhiyun unlock_dir(lower_dir_dentry);
200*4882a593Smuzhiyun return inode;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun /**
204*4882a593Smuzhiyun * ecryptfs_initialize_file
205*4882a593Smuzhiyun *
206*4882a593Smuzhiyun * Cause the file to be changed from a basic empty file to an ecryptfs
207*4882a593Smuzhiyun * file with a header and first data page.
208*4882a593Smuzhiyun *
209*4882a593Smuzhiyun * Returns zero on success
210*4882a593Smuzhiyun */
ecryptfs_initialize_file(struct dentry * ecryptfs_dentry,struct inode * ecryptfs_inode)211*4882a593Smuzhiyun int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
212*4882a593Smuzhiyun struct inode *ecryptfs_inode)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun struct ecryptfs_crypt_stat *crypt_stat =
215*4882a593Smuzhiyun &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
216*4882a593Smuzhiyun int rc = 0;
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun if (S_ISDIR(ecryptfs_inode->i_mode)) {
219*4882a593Smuzhiyun ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
220*4882a593Smuzhiyun crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
221*4882a593Smuzhiyun goto out;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
224*4882a593Smuzhiyun rc = ecryptfs_new_file_context(ecryptfs_inode);
225*4882a593Smuzhiyun if (rc) {
226*4882a593Smuzhiyun ecryptfs_printk(KERN_ERR, "Error creating new file "
227*4882a593Smuzhiyun "context; rc = [%d]\n", rc);
228*4882a593Smuzhiyun goto out;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode);
231*4882a593Smuzhiyun if (rc) {
232*4882a593Smuzhiyun printk(KERN_ERR "%s: Error attempting to initialize "
233*4882a593Smuzhiyun "the lower file for the dentry with name "
234*4882a593Smuzhiyun "[%pd]; rc = [%d]\n", __func__,
235*4882a593Smuzhiyun ecryptfs_dentry, rc);
236*4882a593Smuzhiyun goto out;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode);
239*4882a593Smuzhiyun if (rc)
240*4882a593Smuzhiyun printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
241*4882a593Smuzhiyun ecryptfs_put_lower_file(ecryptfs_inode);
242*4882a593Smuzhiyun out:
243*4882a593Smuzhiyun return rc;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /**
247*4882a593Smuzhiyun * ecryptfs_create
248*4882a593Smuzhiyun * @dir: The inode of the directory in which to create the file.
249*4882a593Smuzhiyun * @dentry: The eCryptfs dentry
250*4882a593Smuzhiyun * @mode: The mode of the new file.
251*4882a593Smuzhiyun *
252*4882a593Smuzhiyun * Creates a new file.
253*4882a593Smuzhiyun *
254*4882a593Smuzhiyun * Returns zero on success; non-zero on error condition
255*4882a593Smuzhiyun */
256*4882a593Smuzhiyun static int
ecryptfs_create(struct inode * directory_inode,struct dentry * ecryptfs_dentry,umode_t mode,bool excl)257*4882a593Smuzhiyun ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
258*4882a593Smuzhiyun umode_t mode, bool excl)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun struct inode *ecryptfs_inode;
261*4882a593Smuzhiyun int rc;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry,
264*4882a593Smuzhiyun mode);
265*4882a593Smuzhiyun if (IS_ERR(ecryptfs_inode)) {
266*4882a593Smuzhiyun ecryptfs_printk(KERN_WARNING, "Failed to create file in"
267*4882a593Smuzhiyun "lower filesystem\n");
268*4882a593Smuzhiyun rc = PTR_ERR(ecryptfs_inode);
269*4882a593Smuzhiyun goto out;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun /* At this point, a file exists on "disk"; we need to make sure
272*4882a593Smuzhiyun * that this on disk file is prepared to be an ecryptfs file */
273*4882a593Smuzhiyun rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode);
274*4882a593Smuzhiyun if (rc) {
275*4882a593Smuzhiyun ecryptfs_do_unlink(directory_inode, ecryptfs_dentry,
276*4882a593Smuzhiyun ecryptfs_inode);
277*4882a593Smuzhiyun iget_failed(ecryptfs_inode);
278*4882a593Smuzhiyun goto out;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun d_instantiate_new(ecryptfs_dentry, ecryptfs_inode);
281*4882a593Smuzhiyun out:
282*4882a593Smuzhiyun return rc;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
ecryptfs_i_size_read(struct dentry * dentry,struct inode * inode)285*4882a593Smuzhiyun static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun struct ecryptfs_crypt_stat *crypt_stat;
288*4882a593Smuzhiyun int rc;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun rc = ecryptfs_get_lower_file(dentry, inode);
291*4882a593Smuzhiyun if (rc) {
292*4882a593Smuzhiyun printk(KERN_ERR "%s: Error attempting to initialize "
293*4882a593Smuzhiyun "the lower file for the dentry with name "
294*4882a593Smuzhiyun "[%pd]; rc = [%d]\n", __func__,
295*4882a593Smuzhiyun dentry, rc);
296*4882a593Smuzhiyun return rc;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
300*4882a593Smuzhiyun /* TODO: lock for crypt_stat comparison */
301*4882a593Smuzhiyun if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
302*4882a593Smuzhiyun ecryptfs_set_default_sizes(crypt_stat);
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun rc = ecryptfs_read_and_validate_header_region(inode);
305*4882a593Smuzhiyun ecryptfs_put_lower_file(inode);
306*4882a593Smuzhiyun if (rc) {
307*4882a593Smuzhiyun rc = ecryptfs_read_and_validate_xattr_region(dentry, inode);
308*4882a593Smuzhiyun if (!rc)
309*4882a593Smuzhiyun crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /* Must return 0 to allow non-eCryptfs files to be looked up, too */
313*4882a593Smuzhiyun return 0;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun /**
317*4882a593Smuzhiyun * ecryptfs_lookup_interpose - Dentry interposition for a lookup
318*4882a593Smuzhiyun */
ecryptfs_lookup_interpose(struct dentry * dentry,struct dentry * lower_dentry)319*4882a593Smuzhiyun static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
320*4882a593Smuzhiyun struct dentry *lower_dentry)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun struct path *path = ecryptfs_dentry_to_lower_path(dentry->d_parent);
323*4882a593Smuzhiyun struct inode *inode, *lower_inode;
324*4882a593Smuzhiyun struct ecryptfs_dentry_info *dentry_info;
325*4882a593Smuzhiyun int rc = 0;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
328*4882a593Smuzhiyun if (!dentry_info) {
329*4882a593Smuzhiyun dput(lower_dentry);
330*4882a593Smuzhiyun return ERR_PTR(-ENOMEM);
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun fsstack_copy_attr_atime(d_inode(dentry->d_parent),
334*4882a593Smuzhiyun d_inode(path->dentry));
335*4882a593Smuzhiyun BUG_ON(!d_count(lower_dentry));
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun ecryptfs_set_dentry_private(dentry, dentry_info);
338*4882a593Smuzhiyun dentry_info->lower_path.mnt = mntget(path->mnt);
339*4882a593Smuzhiyun dentry_info->lower_path.dentry = lower_dentry;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun /*
342*4882a593Smuzhiyun * negative dentry can go positive under us here - its parent is not
343*4882a593Smuzhiyun * locked. That's OK and that could happen just as we return from
344*4882a593Smuzhiyun * ecryptfs_lookup() anyway. Just need to be careful and fetch
345*4882a593Smuzhiyun * ->d_inode only once - it's not stable here.
346*4882a593Smuzhiyun */
347*4882a593Smuzhiyun lower_inode = READ_ONCE(lower_dentry->d_inode);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun if (!lower_inode) {
350*4882a593Smuzhiyun /* We want to add because we couldn't find in lower */
351*4882a593Smuzhiyun d_add(dentry, NULL);
352*4882a593Smuzhiyun return NULL;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun inode = __ecryptfs_get_inode(lower_inode, dentry->d_sb);
355*4882a593Smuzhiyun if (IS_ERR(inode)) {
356*4882a593Smuzhiyun printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n",
357*4882a593Smuzhiyun __func__, PTR_ERR(inode));
358*4882a593Smuzhiyun return ERR_CAST(inode);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun if (S_ISREG(inode->i_mode)) {
361*4882a593Smuzhiyun rc = ecryptfs_i_size_read(dentry, inode);
362*4882a593Smuzhiyun if (rc) {
363*4882a593Smuzhiyun make_bad_inode(inode);
364*4882a593Smuzhiyun return ERR_PTR(rc);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun if (inode->i_state & I_NEW)
369*4882a593Smuzhiyun unlock_new_inode(inode);
370*4882a593Smuzhiyun return d_splice_alias(inode, dentry);
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun /**
374*4882a593Smuzhiyun * ecryptfs_lookup
375*4882a593Smuzhiyun * @ecryptfs_dir_inode: The eCryptfs directory inode
376*4882a593Smuzhiyun * @ecryptfs_dentry: The eCryptfs dentry that we are looking up
377*4882a593Smuzhiyun * @flags: lookup flags
378*4882a593Smuzhiyun *
379*4882a593Smuzhiyun * Find a file on disk. If the file does not exist, then we'll add it to the
380*4882a593Smuzhiyun * dentry cache and continue on to read it from the disk.
381*4882a593Smuzhiyun */
ecryptfs_lookup(struct inode * ecryptfs_dir_inode,struct dentry * ecryptfs_dentry,unsigned int flags)382*4882a593Smuzhiyun static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
383*4882a593Smuzhiyun struct dentry *ecryptfs_dentry,
384*4882a593Smuzhiyun unsigned int flags)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun char *encrypted_and_encoded_name = NULL;
387*4882a593Smuzhiyun struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
388*4882a593Smuzhiyun struct dentry *lower_dir_dentry, *lower_dentry;
389*4882a593Smuzhiyun const char *name = ecryptfs_dentry->d_name.name;
390*4882a593Smuzhiyun size_t len = ecryptfs_dentry->d_name.len;
391*4882a593Smuzhiyun struct dentry *res;
392*4882a593Smuzhiyun int rc = 0;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent);
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun mount_crypt_stat = &ecryptfs_superblock_to_private(
397*4882a593Smuzhiyun ecryptfs_dentry->d_sb)->mount_crypt_stat;
398*4882a593Smuzhiyun if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
399*4882a593Smuzhiyun rc = ecryptfs_encrypt_and_encode_filename(
400*4882a593Smuzhiyun &encrypted_and_encoded_name, &len,
401*4882a593Smuzhiyun mount_crypt_stat, name, len);
402*4882a593Smuzhiyun if (rc) {
403*4882a593Smuzhiyun printk(KERN_ERR "%s: Error attempting to encrypt and encode "
404*4882a593Smuzhiyun "filename; rc = [%d]\n", __func__, rc);
405*4882a593Smuzhiyun return ERR_PTR(rc);
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun name = encrypted_and_encoded_name;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun lower_dentry = lookup_one_len_unlocked(name, lower_dir_dentry, len);
411*4882a593Smuzhiyun if (IS_ERR(lower_dentry)) {
412*4882a593Smuzhiyun ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
413*4882a593Smuzhiyun "[%ld] on lower_dentry = [%s]\n", __func__,
414*4882a593Smuzhiyun PTR_ERR(lower_dentry),
415*4882a593Smuzhiyun name);
416*4882a593Smuzhiyun res = ERR_CAST(lower_dentry);
417*4882a593Smuzhiyun } else {
418*4882a593Smuzhiyun res = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry);
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun kfree(encrypted_and_encoded_name);
421*4882a593Smuzhiyun return res;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
ecryptfs_link(struct dentry * old_dentry,struct inode * dir,struct dentry * new_dentry)424*4882a593Smuzhiyun static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
425*4882a593Smuzhiyun struct dentry *new_dentry)
426*4882a593Smuzhiyun {
427*4882a593Smuzhiyun struct dentry *lower_old_dentry;
428*4882a593Smuzhiyun struct dentry *lower_new_dentry;
429*4882a593Smuzhiyun struct dentry *lower_dir_dentry;
430*4882a593Smuzhiyun u64 file_size_save;
431*4882a593Smuzhiyun int rc;
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun file_size_save = i_size_read(d_inode(old_dentry));
434*4882a593Smuzhiyun lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
435*4882a593Smuzhiyun lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
436*4882a593Smuzhiyun dget(lower_old_dentry);
437*4882a593Smuzhiyun dget(lower_new_dentry);
438*4882a593Smuzhiyun lower_dir_dentry = lock_parent(lower_new_dentry);
439*4882a593Smuzhiyun rc = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry),
440*4882a593Smuzhiyun lower_new_dentry, NULL);
441*4882a593Smuzhiyun if (rc || d_really_is_negative(lower_new_dentry))
442*4882a593Smuzhiyun goto out_lock;
443*4882a593Smuzhiyun rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
444*4882a593Smuzhiyun if (rc)
445*4882a593Smuzhiyun goto out_lock;
446*4882a593Smuzhiyun fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
447*4882a593Smuzhiyun fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
448*4882a593Smuzhiyun set_nlink(d_inode(old_dentry),
449*4882a593Smuzhiyun ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink);
450*4882a593Smuzhiyun i_size_write(d_inode(new_dentry), file_size_save);
451*4882a593Smuzhiyun out_lock:
452*4882a593Smuzhiyun unlock_dir(lower_dir_dentry);
453*4882a593Smuzhiyun dput(lower_new_dentry);
454*4882a593Smuzhiyun dput(lower_old_dentry);
455*4882a593Smuzhiyun return rc;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun
ecryptfs_unlink(struct inode * dir,struct dentry * dentry)458*4882a593Smuzhiyun static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun return ecryptfs_do_unlink(dir, dentry, d_inode(dentry));
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
ecryptfs_symlink(struct inode * dir,struct dentry * dentry,const char * symname)463*4882a593Smuzhiyun static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
464*4882a593Smuzhiyun const char *symname)
465*4882a593Smuzhiyun {
466*4882a593Smuzhiyun int rc;
467*4882a593Smuzhiyun struct dentry *lower_dentry;
468*4882a593Smuzhiyun struct dentry *lower_dir_dentry;
469*4882a593Smuzhiyun char *encoded_symname;
470*4882a593Smuzhiyun size_t encoded_symlen;
471*4882a593Smuzhiyun struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
474*4882a593Smuzhiyun dget(lower_dentry);
475*4882a593Smuzhiyun lower_dir_dentry = lock_parent(lower_dentry);
476*4882a593Smuzhiyun mount_crypt_stat = &ecryptfs_superblock_to_private(
477*4882a593Smuzhiyun dir->i_sb)->mount_crypt_stat;
478*4882a593Smuzhiyun rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname,
479*4882a593Smuzhiyun &encoded_symlen,
480*4882a593Smuzhiyun mount_crypt_stat, symname,
481*4882a593Smuzhiyun strlen(symname));
482*4882a593Smuzhiyun if (rc)
483*4882a593Smuzhiyun goto out_lock;
484*4882a593Smuzhiyun rc = vfs_symlink(d_inode(lower_dir_dentry), lower_dentry,
485*4882a593Smuzhiyun encoded_symname);
486*4882a593Smuzhiyun kfree(encoded_symname);
487*4882a593Smuzhiyun if (rc || d_really_is_negative(lower_dentry))
488*4882a593Smuzhiyun goto out_lock;
489*4882a593Smuzhiyun rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
490*4882a593Smuzhiyun if (rc)
491*4882a593Smuzhiyun goto out_lock;
492*4882a593Smuzhiyun fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
493*4882a593Smuzhiyun fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
494*4882a593Smuzhiyun out_lock:
495*4882a593Smuzhiyun unlock_dir(lower_dir_dentry);
496*4882a593Smuzhiyun dput(lower_dentry);
497*4882a593Smuzhiyun if (d_really_is_negative(dentry))
498*4882a593Smuzhiyun d_drop(dentry);
499*4882a593Smuzhiyun return rc;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
ecryptfs_mkdir(struct inode * dir,struct dentry * dentry,umode_t mode)502*4882a593Smuzhiyun static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun int rc;
505*4882a593Smuzhiyun struct dentry *lower_dentry;
506*4882a593Smuzhiyun struct dentry *lower_dir_dentry;
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
509*4882a593Smuzhiyun lower_dir_dentry = lock_parent(lower_dentry);
510*4882a593Smuzhiyun rc = vfs_mkdir(d_inode(lower_dir_dentry), lower_dentry, mode);
511*4882a593Smuzhiyun if (rc || d_really_is_negative(lower_dentry))
512*4882a593Smuzhiyun goto out;
513*4882a593Smuzhiyun rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
514*4882a593Smuzhiyun if (rc)
515*4882a593Smuzhiyun goto out;
516*4882a593Smuzhiyun fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
517*4882a593Smuzhiyun fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
518*4882a593Smuzhiyun set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink);
519*4882a593Smuzhiyun out:
520*4882a593Smuzhiyun unlock_dir(lower_dir_dentry);
521*4882a593Smuzhiyun if (d_really_is_negative(dentry))
522*4882a593Smuzhiyun d_drop(dentry);
523*4882a593Smuzhiyun return rc;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun
ecryptfs_rmdir(struct inode * dir,struct dentry * dentry)526*4882a593Smuzhiyun static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun struct dentry *lower_dentry;
529*4882a593Smuzhiyun struct dentry *lower_dir_dentry;
530*4882a593Smuzhiyun struct inode *lower_dir_inode;
531*4882a593Smuzhiyun int rc;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
534*4882a593Smuzhiyun lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
535*4882a593Smuzhiyun lower_dir_inode = d_inode(lower_dir_dentry);
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT);
538*4882a593Smuzhiyun dget(lower_dentry); // don't even try to make the lower negative
539*4882a593Smuzhiyun if (lower_dentry->d_parent != lower_dir_dentry)
540*4882a593Smuzhiyun rc = -EINVAL;
541*4882a593Smuzhiyun else if (d_unhashed(lower_dentry))
542*4882a593Smuzhiyun rc = -EINVAL;
543*4882a593Smuzhiyun else
544*4882a593Smuzhiyun rc = vfs_rmdir(lower_dir_inode, lower_dentry);
545*4882a593Smuzhiyun if (!rc) {
546*4882a593Smuzhiyun clear_nlink(d_inode(dentry));
547*4882a593Smuzhiyun fsstack_copy_attr_times(dir, lower_dir_inode);
548*4882a593Smuzhiyun set_nlink(dir, lower_dir_inode->i_nlink);
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun dput(lower_dentry);
551*4882a593Smuzhiyun inode_unlock(lower_dir_inode);
552*4882a593Smuzhiyun if (!rc)
553*4882a593Smuzhiyun d_drop(dentry);
554*4882a593Smuzhiyun return rc;
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun static int
ecryptfs_mknod(struct inode * dir,struct dentry * dentry,umode_t mode,dev_t dev)558*4882a593Smuzhiyun ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
559*4882a593Smuzhiyun {
560*4882a593Smuzhiyun int rc;
561*4882a593Smuzhiyun struct dentry *lower_dentry;
562*4882a593Smuzhiyun struct dentry *lower_dir_dentry;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
565*4882a593Smuzhiyun lower_dir_dentry = lock_parent(lower_dentry);
566*4882a593Smuzhiyun rc = vfs_mknod(d_inode(lower_dir_dentry), lower_dentry, mode, dev);
567*4882a593Smuzhiyun if (rc || d_really_is_negative(lower_dentry))
568*4882a593Smuzhiyun goto out;
569*4882a593Smuzhiyun rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
570*4882a593Smuzhiyun if (rc)
571*4882a593Smuzhiyun goto out;
572*4882a593Smuzhiyun fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
573*4882a593Smuzhiyun fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
574*4882a593Smuzhiyun out:
575*4882a593Smuzhiyun unlock_dir(lower_dir_dentry);
576*4882a593Smuzhiyun if (d_really_is_negative(dentry))
577*4882a593Smuzhiyun d_drop(dentry);
578*4882a593Smuzhiyun return rc;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun static int
ecryptfs_rename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)582*4882a593Smuzhiyun ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
583*4882a593Smuzhiyun struct inode *new_dir, struct dentry *new_dentry,
584*4882a593Smuzhiyun unsigned int flags)
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun int rc;
587*4882a593Smuzhiyun struct dentry *lower_old_dentry;
588*4882a593Smuzhiyun struct dentry *lower_new_dentry;
589*4882a593Smuzhiyun struct dentry *lower_old_dir_dentry;
590*4882a593Smuzhiyun struct dentry *lower_new_dir_dentry;
591*4882a593Smuzhiyun struct dentry *trap;
592*4882a593Smuzhiyun struct inode *target_inode;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun if (flags)
595*4882a593Smuzhiyun return -EINVAL;
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun lower_old_dir_dentry = ecryptfs_dentry_to_lower(old_dentry->d_parent);
598*4882a593Smuzhiyun lower_new_dir_dentry = ecryptfs_dentry_to_lower(new_dentry->d_parent);
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
601*4882a593Smuzhiyun lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun target_inode = d_inode(new_dentry);
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
606*4882a593Smuzhiyun dget(lower_new_dentry);
607*4882a593Smuzhiyun rc = -EINVAL;
608*4882a593Smuzhiyun if (lower_old_dentry->d_parent != lower_old_dir_dentry)
609*4882a593Smuzhiyun goto out_lock;
610*4882a593Smuzhiyun if (lower_new_dentry->d_parent != lower_new_dir_dentry)
611*4882a593Smuzhiyun goto out_lock;
612*4882a593Smuzhiyun if (d_unhashed(lower_old_dentry) || d_unhashed(lower_new_dentry))
613*4882a593Smuzhiyun goto out_lock;
614*4882a593Smuzhiyun /* source should not be ancestor of target */
615*4882a593Smuzhiyun if (trap == lower_old_dentry)
616*4882a593Smuzhiyun goto out_lock;
617*4882a593Smuzhiyun /* target should not be ancestor of source */
618*4882a593Smuzhiyun if (trap == lower_new_dentry) {
619*4882a593Smuzhiyun rc = -ENOTEMPTY;
620*4882a593Smuzhiyun goto out_lock;
621*4882a593Smuzhiyun }
622*4882a593Smuzhiyun rc = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
623*4882a593Smuzhiyun d_inode(lower_new_dir_dentry), lower_new_dentry,
624*4882a593Smuzhiyun NULL, 0);
625*4882a593Smuzhiyun if (rc)
626*4882a593Smuzhiyun goto out_lock;
627*4882a593Smuzhiyun if (target_inode)
628*4882a593Smuzhiyun fsstack_copy_attr_all(target_inode,
629*4882a593Smuzhiyun ecryptfs_inode_to_lower(target_inode));
630*4882a593Smuzhiyun fsstack_copy_attr_all(new_dir, d_inode(lower_new_dir_dentry));
631*4882a593Smuzhiyun if (new_dir != old_dir)
632*4882a593Smuzhiyun fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry));
633*4882a593Smuzhiyun out_lock:
634*4882a593Smuzhiyun dput(lower_new_dentry);
635*4882a593Smuzhiyun unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
636*4882a593Smuzhiyun return rc;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun
ecryptfs_readlink_lower(struct dentry * dentry,size_t * bufsiz)639*4882a593Smuzhiyun static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun DEFINE_DELAYED_CALL(done);
642*4882a593Smuzhiyun struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
643*4882a593Smuzhiyun const char *link;
644*4882a593Smuzhiyun char *buf;
645*4882a593Smuzhiyun int rc;
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun link = vfs_get_link(lower_dentry, &done);
648*4882a593Smuzhiyun if (IS_ERR(link))
649*4882a593Smuzhiyun return ERR_CAST(link);
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
652*4882a593Smuzhiyun link, strlen(link));
653*4882a593Smuzhiyun do_delayed_call(&done);
654*4882a593Smuzhiyun if (rc)
655*4882a593Smuzhiyun return ERR_PTR(rc);
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun return buf;
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
ecryptfs_get_link(struct dentry * dentry,struct inode * inode,struct delayed_call * done)660*4882a593Smuzhiyun static const char *ecryptfs_get_link(struct dentry *dentry,
661*4882a593Smuzhiyun struct inode *inode,
662*4882a593Smuzhiyun struct delayed_call *done)
663*4882a593Smuzhiyun {
664*4882a593Smuzhiyun size_t len;
665*4882a593Smuzhiyun char *buf;
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun if (!dentry)
668*4882a593Smuzhiyun return ERR_PTR(-ECHILD);
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun buf = ecryptfs_readlink_lower(dentry, &len);
671*4882a593Smuzhiyun if (IS_ERR(buf))
672*4882a593Smuzhiyun return buf;
673*4882a593Smuzhiyun fsstack_copy_attr_atime(d_inode(dentry),
674*4882a593Smuzhiyun d_inode(ecryptfs_dentry_to_lower(dentry)));
675*4882a593Smuzhiyun buf[len] = '\0';
676*4882a593Smuzhiyun set_delayed_call(done, kfree_link, buf);
677*4882a593Smuzhiyun return buf;
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun /**
681*4882a593Smuzhiyun * upper_size_to_lower_size
682*4882a593Smuzhiyun * @crypt_stat: Crypt_stat associated with file
683*4882a593Smuzhiyun * @upper_size: Size of the upper file
684*4882a593Smuzhiyun *
685*4882a593Smuzhiyun * Calculate the required size of the lower file based on the
686*4882a593Smuzhiyun * specified size of the upper file. This calculation is based on the
687*4882a593Smuzhiyun * number of headers in the underlying file and the extent size.
688*4882a593Smuzhiyun *
689*4882a593Smuzhiyun * Returns Calculated size of the lower file.
690*4882a593Smuzhiyun */
691*4882a593Smuzhiyun static loff_t
upper_size_to_lower_size(struct ecryptfs_crypt_stat * crypt_stat,loff_t upper_size)692*4882a593Smuzhiyun upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
693*4882a593Smuzhiyun loff_t upper_size)
694*4882a593Smuzhiyun {
695*4882a593Smuzhiyun loff_t lower_size;
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun lower_size = ecryptfs_lower_header_size(crypt_stat);
698*4882a593Smuzhiyun if (upper_size != 0) {
699*4882a593Smuzhiyun loff_t num_extents;
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun num_extents = upper_size >> crypt_stat->extent_shift;
702*4882a593Smuzhiyun if (upper_size & ~crypt_stat->extent_mask)
703*4882a593Smuzhiyun num_extents++;
704*4882a593Smuzhiyun lower_size += (num_extents * crypt_stat->extent_size);
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun return lower_size;
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun /**
710*4882a593Smuzhiyun * truncate_upper
711*4882a593Smuzhiyun * @dentry: The ecryptfs layer dentry
712*4882a593Smuzhiyun * @ia: Address of the ecryptfs inode's attributes
713*4882a593Smuzhiyun * @lower_ia: Address of the lower inode's attributes
714*4882a593Smuzhiyun *
715*4882a593Smuzhiyun * Function to handle truncations modifying the size of the file. Note
716*4882a593Smuzhiyun * that the file sizes are interpolated. When expanding, we are simply
717*4882a593Smuzhiyun * writing strings of 0's out. When truncating, we truncate the upper
718*4882a593Smuzhiyun * inode and update the lower_ia according to the page index
719*4882a593Smuzhiyun * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return,
720*4882a593Smuzhiyun * the caller must use lower_ia in a call to notify_change() to perform
721*4882a593Smuzhiyun * the truncation of the lower inode.
722*4882a593Smuzhiyun *
723*4882a593Smuzhiyun * Returns zero on success; non-zero otherwise
724*4882a593Smuzhiyun */
truncate_upper(struct dentry * dentry,struct iattr * ia,struct iattr * lower_ia)725*4882a593Smuzhiyun static int truncate_upper(struct dentry *dentry, struct iattr *ia,
726*4882a593Smuzhiyun struct iattr *lower_ia)
727*4882a593Smuzhiyun {
728*4882a593Smuzhiyun int rc = 0;
729*4882a593Smuzhiyun struct inode *inode = d_inode(dentry);
730*4882a593Smuzhiyun struct ecryptfs_crypt_stat *crypt_stat;
731*4882a593Smuzhiyun loff_t i_size = i_size_read(inode);
732*4882a593Smuzhiyun loff_t lower_size_before_truncate;
733*4882a593Smuzhiyun loff_t lower_size_after_truncate;
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun if (unlikely((ia->ia_size == i_size))) {
736*4882a593Smuzhiyun lower_ia->ia_valid &= ~ATTR_SIZE;
737*4882a593Smuzhiyun return 0;
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun rc = ecryptfs_get_lower_file(dentry, inode);
740*4882a593Smuzhiyun if (rc)
741*4882a593Smuzhiyun return rc;
742*4882a593Smuzhiyun crypt_stat = &ecryptfs_inode_to_private(d_inode(dentry))->crypt_stat;
743*4882a593Smuzhiyun /* Switch on growing or shrinking file */
744*4882a593Smuzhiyun if (ia->ia_size > i_size) {
745*4882a593Smuzhiyun char zero[] = { 0x00 };
746*4882a593Smuzhiyun
747*4882a593Smuzhiyun lower_ia->ia_valid &= ~ATTR_SIZE;
748*4882a593Smuzhiyun /* Write a single 0 at the last position of the file;
749*4882a593Smuzhiyun * this triggers code that will fill in 0's throughout
750*4882a593Smuzhiyun * the intermediate portion of the previous end of the
751*4882a593Smuzhiyun * file and the new and of the file */
752*4882a593Smuzhiyun rc = ecryptfs_write(inode, zero,
753*4882a593Smuzhiyun (ia->ia_size - 1), 1);
754*4882a593Smuzhiyun } else { /* ia->ia_size < i_size_read(inode) */
755*4882a593Smuzhiyun /* We're chopping off all the pages down to the page
756*4882a593Smuzhiyun * in which ia->ia_size is located. Fill in the end of
757*4882a593Smuzhiyun * that page from (ia->ia_size & ~PAGE_MASK) to
758*4882a593Smuzhiyun * PAGE_SIZE with zeros. */
759*4882a593Smuzhiyun size_t num_zeros = (PAGE_SIZE
760*4882a593Smuzhiyun - (ia->ia_size & ~PAGE_MASK));
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
763*4882a593Smuzhiyun truncate_setsize(inode, ia->ia_size);
764*4882a593Smuzhiyun lower_ia->ia_size = ia->ia_size;
765*4882a593Smuzhiyun lower_ia->ia_valid |= ATTR_SIZE;
766*4882a593Smuzhiyun goto out;
767*4882a593Smuzhiyun }
768*4882a593Smuzhiyun if (num_zeros) {
769*4882a593Smuzhiyun char *zeros_virt;
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun zeros_virt = kzalloc(num_zeros, GFP_KERNEL);
772*4882a593Smuzhiyun if (!zeros_virt) {
773*4882a593Smuzhiyun rc = -ENOMEM;
774*4882a593Smuzhiyun goto out;
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun rc = ecryptfs_write(inode, zeros_virt,
777*4882a593Smuzhiyun ia->ia_size, num_zeros);
778*4882a593Smuzhiyun kfree(zeros_virt);
779*4882a593Smuzhiyun if (rc) {
780*4882a593Smuzhiyun printk(KERN_ERR "Error attempting to zero out "
781*4882a593Smuzhiyun "the remainder of the end page on "
782*4882a593Smuzhiyun "reducing truncate; rc = [%d]\n", rc);
783*4882a593Smuzhiyun goto out;
784*4882a593Smuzhiyun }
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun truncate_setsize(inode, ia->ia_size);
787*4882a593Smuzhiyun rc = ecryptfs_write_inode_size_to_metadata(inode);
788*4882a593Smuzhiyun if (rc) {
789*4882a593Smuzhiyun printk(KERN_ERR "Problem with "
790*4882a593Smuzhiyun "ecryptfs_write_inode_size_to_metadata; "
791*4882a593Smuzhiyun "rc = [%d]\n", rc);
792*4882a593Smuzhiyun goto out;
793*4882a593Smuzhiyun }
794*4882a593Smuzhiyun /* We are reducing the size of the ecryptfs file, and need to
795*4882a593Smuzhiyun * know if we need to reduce the size of the lower file. */
796*4882a593Smuzhiyun lower_size_before_truncate =
797*4882a593Smuzhiyun upper_size_to_lower_size(crypt_stat, i_size);
798*4882a593Smuzhiyun lower_size_after_truncate =
799*4882a593Smuzhiyun upper_size_to_lower_size(crypt_stat, ia->ia_size);
800*4882a593Smuzhiyun if (lower_size_after_truncate < lower_size_before_truncate) {
801*4882a593Smuzhiyun lower_ia->ia_size = lower_size_after_truncate;
802*4882a593Smuzhiyun lower_ia->ia_valid |= ATTR_SIZE;
803*4882a593Smuzhiyun } else
804*4882a593Smuzhiyun lower_ia->ia_valid &= ~ATTR_SIZE;
805*4882a593Smuzhiyun }
806*4882a593Smuzhiyun out:
807*4882a593Smuzhiyun ecryptfs_put_lower_file(inode);
808*4882a593Smuzhiyun return rc;
809*4882a593Smuzhiyun }
810*4882a593Smuzhiyun
ecryptfs_inode_newsize_ok(struct inode * inode,loff_t offset)811*4882a593Smuzhiyun static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset)
812*4882a593Smuzhiyun {
813*4882a593Smuzhiyun struct ecryptfs_crypt_stat *crypt_stat;
814*4882a593Smuzhiyun loff_t lower_oldsize, lower_newsize;
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
817*4882a593Smuzhiyun lower_oldsize = upper_size_to_lower_size(crypt_stat,
818*4882a593Smuzhiyun i_size_read(inode));
819*4882a593Smuzhiyun lower_newsize = upper_size_to_lower_size(crypt_stat, offset);
820*4882a593Smuzhiyun if (lower_newsize > lower_oldsize) {
821*4882a593Smuzhiyun /*
822*4882a593Smuzhiyun * The eCryptfs inode and the new *lower* size are mixed here
823*4882a593Smuzhiyun * because we may not have the lower i_mutex held and/or it may
824*4882a593Smuzhiyun * not be appropriate to call inode_newsize_ok() with inodes
825*4882a593Smuzhiyun * from other filesystems.
826*4882a593Smuzhiyun */
827*4882a593Smuzhiyun return inode_newsize_ok(inode, lower_newsize);
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun return 0;
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun /**
834*4882a593Smuzhiyun * ecryptfs_truncate
835*4882a593Smuzhiyun * @dentry: The ecryptfs layer dentry
836*4882a593Smuzhiyun * @new_length: The length to expand the file to
837*4882a593Smuzhiyun *
838*4882a593Smuzhiyun * Simple function that handles the truncation of an eCryptfs inode and
839*4882a593Smuzhiyun * its corresponding lower inode.
840*4882a593Smuzhiyun *
841*4882a593Smuzhiyun * Returns zero on success; non-zero otherwise
842*4882a593Smuzhiyun */
ecryptfs_truncate(struct dentry * dentry,loff_t new_length)843*4882a593Smuzhiyun int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
844*4882a593Smuzhiyun {
845*4882a593Smuzhiyun struct iattr ia = { .ia_valid = ATTR_SIZE, .ia_size = new_length };
846*4882a593Smuzhiyun struct iattr lower_ia = { .ia_valid = 0 };
847*4882a593Smuzhiyun int rc;
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun rc = ecryptfs_inode_newsize_ok(d_inode(dentry), new_length);
850*4882a593Smuzhiyun if (rc)
851*4882a593Smuzhiyun return rc;
852*4882a593Smuzhiyun
853*4882a593Smuzhiyun rc = truncate_upper(dentry, &ia, &lower_ia);
854*4882a593Smuzhiyun if (!rc && lower_ia.ia_valid & ATTR_SIZE) {
855*4882a593Smuzhiyun struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
856*4882a593Smuzhiyun
857*4882a593Smuzhiyun inode_lock(d_inode(lower_dentry));
858*4882a593Smuzhiyun rc = notify_change(lower_dentry, &lower_ia, NULL);
859*4882a593Smuzhiyun inode_unlock(d_inode(lower_dentry));
860*4882a593Smuzhiyun }
861*4882a593Smuzhiyun return rc;
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun static int
ecryptfs_permission(struct inode * inode,int mask)865*4882a593Smuzhiyun ecryptfs_permission(struct inode *inode, int mask)
866*4882a593Smuzhiyun {
867*4882a593Smuzhiyun return inode_permission(ecryptfs_inode_to_lower(inode), mask);
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun /**
871*4882a593Smuzhiyun * ecryptfs_setattr
872*4882a593Smuzhiyun * @dentry: dentry handle to the inode to modify
873*4882a593Smuzhiyun * @ia: Structure with flags of what to change and values
874*4882a593Smuzhiyun *
875*4882a593Smuzhiyun * Updates the metadata of an inode. If the update is to the size
876*4882a593Smuzhiyun * i.e. truncation, then ecryptfs_truncate will handle the size modification
877*4882a593Smuzhiyun * of both the ecryptfs inode and the lower inode.
878*4882a593Smuzhiyun *
879*4882a593Smuzhiyun * All other metadata changes will be passed right to the lower filesystem,
880*4882a593Smuzhiyun * and we will just update our inode to look like the lower.
881*4882a593Smuzhiyun */
ecryptfs_setattr(struct dentry * dentry,struct iattr * ia)882*4882a593Smuzhiyun static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun int rc = 0;
885*4882a593Smuzhiyun struct dentry *lower_dentry;
886*4882a593Smuzhiyun struct iattr lower_ia;
887*4882a593Smuzhiyun struct inode *inode;
888*4882a593Smuzhiyun struct inode *lower_inode;
889*4882a593Smuzhiyun struct ecryptfs_crypt_stat *crypt_stat;
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun crypt_stat = &ecryptfs_inode_to_private(d_inode(dentry))->crypt_stat;
892*4882a593Smuzhiyun if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) {
893*4882a593Smuzhiyun rc = ecryptfs_init_crypt_stat(crypt_stat);
894*4882a593Smuzhiyun if (rc)
895*4882a593Smuzhiyun return rc;
896*4882a593Smuzhiyun }
897*4882a593Smuzhiyun inode = d_inode(dentry);
898*4882a593Smuzhiyun lower_inode = ecryptfs_inode_to_lower(inode);
899*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
900*4882a593Smuzhiyun mutex_lock(&crypt_stat->cs_mutex);
901*4882a593Smuzhiyun if (d_is_dir(dentry))
902*4882a593Smuzhiyun crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
903*4882a593Smuzhiyun else if (d_is_reg(dentry)
904*4882a593Smuzhiyun && (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
905*4882a593Smuzhiyun || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) {
906*4882a593Smuzhiyun struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun mount_crypt_stat = &ecryptfs_superblock_to_private(
909*4882a593Smuzhiyun dentry->d_sb)->mount_crypt_stat;
910*4882a593Smuzhiyun rc = ecryptfs_get_lower_file(dentry, inode);
911*4882a593Smuzhiyun if (rc) {
912*4882a593Smuzhiyun mutex_unlock(&crypt_stat->cs_mutex);
913*4882a593Smuzhiyun goto out;
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun rc = ecryptfs_read_metadata(dentry);
916*4882a593Smuzhiyun ecryptfs_put_lower_file(inode);
917*4882a593Smuzhiyun if (rc) {
918*4882a593Smuzhiyun if (!(mount_crypt_stat->flags
919*4882a593Smuzhiyun & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
920*4882a593Smuzhiyun rc = -EIO;
921*4882a593Smuzhiyun printk(KERN_WARNING "Either the lower file "
922*4882a593Smuzhiyun "is not in a valid eCryptfs format, "
923*4882a593Smuzhiyun "or the key could not be retrieved. "
924*4882a593Smuzhiyun "Plaintext passthrough mode is not "
925*4882a593Smuzhiyun "enabled; returning -EIO\n");
926*4882a593Smuzhiyun mutex_unlock(&crypt_stat->cs_mutex);
927*4882a593Smuzhiyun goto out;
928*4882a593Smuzhiyun }
929*4882a593Smuzhiyun rc = 0;
930*4882a593Smuzhiyun crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
931*4882a593Smuzhiyun | ECRYPTFS_ENCRYPTED);
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun }
934*4882a593Smuzhiyun mutex_unlock(&crypt_stat->cs_mutex);
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun rc = setattr_prepare(dentry, ia);
937*4882a593Smuzhiyun if (rc)
938*4882a593Smuzhiyun goto out;
939*4882a593Smuzhiyun if (ia->ia_valid & ATTR_SIZE) {
940*4882a593Smuzhiyun rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size);
941*4882a593Smuzhiyun if (rc)
942*4882a593Smuzhiyun goto out;
943*4882a593Smuzhiyun }
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun memcpy(&lower_ia, ia, sizeof(lower_ia));
946*4882a593Smuzhiyun if (ia->ia_valid & ATTR_FILE)
947*4882a593Smuzhiyun lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);
948*4882a593Smuzhiyun if (ia->ia_valid & ATTR_SIZE) {
949*4882a593Smuzhiyun rc = truncate_upper(dentry, ia, &lower_ia);
950*4882a593Smuzhiyun if (rc < 0)
951*4882a593Smuzhiyun goto out;
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun /*
955*4882a593Smuzhiyun * mode change is for clearing setuid/setgid bits. Allow lower fs
956*4882a593Smuzhiyun * to interpret this in its own way.
957*4882a593Smuzhiyun */
958*4882a593Smuzhiyun if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
959*4882a593Smuzhiyun lower_ia.ia_valid &= ~ATTR_MODE;
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun inode_lock(d_inode(lower_dentry));
962*4882a593Smuzhiyun rc = notify_change(lower_dentry, &lower_ia, NULL);
963*4882a593Smuzhiyun inode_unlock(d_inode(lower_dentry));
964*4882a593Smuzhiyun out:
965*4882a593Smuzhiyun fsstack_copy_attr_all(inode, lower_inode);
966*4882a593Smuzhiyun return rc;
967*4882a593Smuzhiyun }
968*4882a593Smuzhiyun
ecryptfs_getattr_link(const struct path * path,struct kstat * stat,u32 request_mask,unsigned int flags)969*4882a593Smuzhiyun static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat,
970*4882a593Smuzhiyun u32 request_mask, unsigned int flags)
971*4882a593Smuzhiyun {
972*4882a593Smuzhiyun struct dentry *dentry = path->dentry;
973*4882a593Smuzhiyun struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
974*4882a593Smuzhiyun int rc = 0;
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun mount_crypt_stat = &ecryptfs_superblock_to_private(
977*4882a593Smuzhiyun dentry->d_sb)->mount_crypt_stat;
978*4882a593Smuzhiyun generic_fillattr(d_inode(dentry), stat);
979*4882a593Smuzhiyun if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
980*4882a593Smuzhiyun char *target;
981*4882a593Smuzhiyun size_t targetsiz;
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun target = ecryptfs_readlink_lower(dentry, &targetsiz);
984*4882a593Smuzhiyun if (!IS_ERR(target)) {
985*4882a593Smuzhiyun kfree(target);
986*4882a593Smuzhiyun stat->size = targetsiz;
987*4882a593Smuzhiyun } else {
988*4882a593Smuzhiyun rc = PTR_ERR(target);
989*4882a593Smuzhiyun }
990*4882a593Smuzhiyun }
991*4882a593Smuzhiyun return rc;
992*4882a593Smuzhiyun }
993*4882a593Smuzhiyun
ecryptfs_getattr(const struct path * path,struct kstat * stat,u32 request_mask,unsigned int flags)994*4882a593Smuzhiyun static int ecryptfs_getattr(const struct path *path, struct kstat *stat,
995*4882a593Smuzhiyun u32 request_mask, unsigned int flags)
996*4882a593Smuzhiyun {
997*4882a593Smuzhiyun struct dentry *dentry = path->dentry;
998*4882a593Smuzhiyun struct kstat lower_stat;
999*4882a593Smuzhiyun int rc;
1000*4882a593Smuzhiyun
1001*4882a593Smuzhiyun rc = vfs_getattr(ecryptfs_dentry_to_lower_path(dentry), &lower_stat,
1002*4882a593Smuzhiyun request_mask, flags);
1003*4882a593Smuzhiyun if (!rc) {
1004*4882a593Smuzhiyun fsstack_copy_attr_all(d_inode(dentry),
1005*4882a593Smuzhiyun ecryptfs_inode_to_lower(d_inode(dentry)));
1006*4882a593Smuzhiyun generic_fillattr(d_inode(dentry), stat);
1007*4882a593Smuzhiyun stat->blocks = lower_stat.blocks;
1008*4882a593Smuzhiyun }
1009*4882a593Smuzhiyun return rc;
1010*4882a593Smuzhiyun }
1011*4882a593Smuzhiyun
1012*4882a593Smuzhiyun int
ecryptfs_setxattr(struct dentry * dentry,struct inode * inode,const char * name,const void * value,size_t size,int flags)1013*4882a593Smuzhiyun ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
1014*4882a593Smuzhiyun const char *name, const void *value,
1015*4882a593Smuzhiyun size_t size, int flags)
1016*4882a593Smuzhiyun {
1017*4882a593Smuzhiyun int rc;
1018*4882a593Smuzhiyun struct dentry *lower_dentry;
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
1021*4882a593Smuzhiyun if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) {
1022*4882a593Smuzhiyun rc = -EOPNOTSUPP;
1023*4882a593Smuzhiyun goto out;
1024*4882a593Smuzhiyun }
1025*4882a593Smuzhiyun rc = vfs_setxattr(lower_dentry, name, value, size, flags);
1026*4882a593Smuzhiyun if (!rc && inode)
1027*4882a593Smuzhiyun fsstack_copy_attr_all(inode, d_inode(lower_dentry));
1028*4882a593Smuzhiyun out:
1029*4882a593Smuzhiyun return rc;
1030*4882a593Smuzhiyun }
1031*4882a593Smuzhiyun
1032*4882a593Smuzhiyun ssize_t
ecryptfs_getxattr_lower(struct dentry * lower_dentry,struct inode * lower_inode,const char * name,void * value,size_t size)1033*4882a593Smuzhiyun ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
1034*4882a593Smuzhiyun const char *name, void *value, size_t size)
1035*4882a593Smuzhiyun {
1036*4882a593Smuzhiyun int rc;
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun if (!(lower_inode->i_opflags & IOP_XATTR)) {
1039*4882a593Smuzhiyun rc = -EOPNOTSUPP;
1040*4882a593Smuzhiyun goto out;
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun inode_lock(lower_inode);
1043*4882a593Smuzhiyun rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size,
1044*4882a593Smuzhiyun XATTR_NOSECURITY);
1045*4882a593Smuzhiyun inode_unlock(lower_inode);
1046*4882a593Smuzhiyun out:
1047*4882a593Smuzhiyun return rc;
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun
1050*4882a593Smuzhiyun static ssize_t
ecryptfs_getxattr(struct dentry * dentry,struct inode * inode,const char * name,void * value,size_t size)1051*4882a593Smuzhiyun ecryptfs_getxattr(struct dentry *dentry, struct inode *inode,
1052*4882a593Smuzhiyun const char *name, void *value, size_t size)
1053*4882a593Smuzhiyun {
1054*4882a593Smuzhiyun return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry),
1055*4882a593Smuzhiyun ecryptfs_inode_to_lower(inode),
1056*4882a593Smuzhiyun name, value, size);
1057*4882a593Smuzhiyun }
1058*4882a593Smuzhiyun
1059*4882a593Smuzhiyun static ssize_t
ecryptfs_listxattr(struct dentry * dentry,char * list,size_t size)1060*4882a593Smuzhiyun ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
1061*4882a593Smuzhiyun {
1062*4882a593Smuzhiyun int rc = 0;
1063*4882a593Smuzhiyun struct dentry *lower_dentry;
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
1066*4882a593Smuzhiyun if (!d_inode(lower_dentry)->i_op->listxattr) {
1067*4882a593Smuzhiyun rc = -EOPNOTSUPP;
1068*4882a593Smuzhiyun goto out;
1069*4882a593Smuzhiyun }
1070*4882a593Smuzhiyun inode_lock(d_inode(lower_dentry));
1071*4882a593Smuzhiyun rc = d_inode(lower_dentry)->i_op->listxattr(lower_dentry, list, size);
1072*4882a593Smuzhiyun inode_unlock(d_inode(lower_dentry));
1073*4882a593Smuzhiyun out:
1074*4882a593Smuzhiyun return rc;
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun
ecryptfs_removexattr(struct dentry * dentry,struct inode * inode,const char * name)1077*4882a593Smuzhiyun static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
1078*4882a593Smuzhiyun const char *name)
1079*4882a593Smuzhiyun {
1080*4882a593Smuzhiyun int rc;
1081*4882a593Smuzhiyun struct dentry *lower_dentry;
1082*4882a593Smuzhiyun struct inode *lower_inode;
1083*4882a593Smuzhiyun
1084*4882a593Smuzhiyun lower_dentry = ecryptfs_dentry_to_lower(dentry);
1085*4882a593Smuzhiyun lower_inode = ecryptfs_inode_to_lower(inode);
1086*4882a593Smuzhiyun if (!(lower_inode->i_opflags & IOP_XATTR)) {
1087*4882a593Smuzhiyun rc = -EOPNOTSUPP;
1088*4882a593Smuzhiyun goto out;
1089*4882a593Smuzhiyun }
1090*4882a593Smuzhiyun inode_lock(lower_inode);
1091*4882a593Smuzhiyun rc = __vfs_removexattr(lower_dentry, name);
1092*4882a593Smuzhiyun inode_unlock(lower_inode);
1093*4882a593Smuzhiyun out:
1094*4882a593Smuzhiyun return rc;
1095*4882a593Smuzhiyun }
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun const struct inode_operations ecryptfs_symlink_iops = {
1098*4882a593Smuzhiyun .get_link = ecryptfs_get_link,
1099*4882a593Smuzhiyun .permission = ecryptfs_permission,
1100*4882a593Smuzhiyun .setattr = ecryptfs_setattr,
1101*4882a593Smuzhiyun .getattr = ecryptfs_getattr_link,
1102*4882a593Smuzhiyun .listxattr = ecryptfs_listxattr,
1103*4882a593Smuzhiyun };
1104*4882a593Smuzhiyun
1105*4882a593Smuzhiyun const struct inode_operations ecryptfs_dir_iops = {
1106*4882a593Smuzhiyun .create = ecryptfs_create,
1107*4882a593Smuzhiyun .lookup = ecryptfs_lookup,
1108*4882a593Smuzhiyun .link = ecryptfs_link,
1109*4882a593Smuzhiyun .unlink = ecryptfs_unlink,
1110*4882a593Smuzhiyun .symlink = ecryptfs_symlink,
1111*4882a593Smuzhiyun .mkdir = ecryptfs_mkdir,
1112*4882a593Smuzhiyun .rmdir = ecryptfs_rmdir,
1113*4882a593Smuzhiyun .mknod = ecryptfs_mknod,
1114*4882a593Smuzhiyun .rename = ecryptfs_rename,
1115*4882a593Smuzhiyun .permission = ecryptfs_permission,
1116*4882a593Smuzhiyun .setattr = ecryptfs_setattr,
1117*4882a593Smuzhiyun .listxattr = ecryptfs_listxattr,
1118*4882a593Smuzhiyun };
1119*4882a593Smuzhiyun
1120*4882a593Smuzhiyun const struct inode_operations ecryptfs_main_iops = {
1121*4882a593Smuzhiyun .permission = ecryptfs_permission,
1122*4882a593Smuzhiyun .setattr = ecryptfs_setattr,
1123*4882a593Smuzhiyun .getattr = ecryptfs_getattr,
1124*4882a593Smuzhiyun .listxattr = ecryptfs_listxattr,
1125*4882a593Smuzhiyun };
1126*4882a593Smuzhiyun
ecryptfs_xattr_get(const struct xattr_handler * handler,struct dentry * dentry,struct inode * inode,const char * name,void * buffer,size_t size,int flags)1127*4882a593Smuzhiyun static int ecryptfs_xattr_get(const struct xattr_handler *handler,
1128*4882a593Smuzhiyun struct dentry *dentry, struct inode *inode,
1129*4882a593Smuzhiyun const char *name, void *buffer, size_t size,
1130*4882a593Smuzhiyun int flags)
1131*4882a593Smuzhiyun {
1132*4882a593Smuzhiyun return ecryptfs_getxattr(dentry, inode, name, buffer, size);
1133*4882a593Smuzhiyun }
1134*4882a593Smuzhiyun
ecryptfs_xattr_set(const struct xattr_handler * handler,struct dentry * dentry,struct inode * inode,const char * name,const void * value,size_t size,int flags)1135*4882a593Smuzhiyun static int ecryptfs_xattr_set(const struct xattr_handler *handler,
1136*4882a593Smuzhiyun struct dentry *dentry, struct inode *inode,
1137*4882a593Smuzhiyun const char *name, const void *value, size_t size,
1138*4882a593Smuzhiyun int flags)
1139*4882a593Smuzhiyun {
1140*4882a593Smuzhiyun if (value)
1141*4882a593Smuzhiyun return ecryptfs_setxattr(dentry, inode, name, value, size, flags);
1142*4882a593Smuzhiyun else {
1143*4882a593Smuzhiyun BUG_ON(flags != XATTR_REPLACE);
1144*4882a593Smuzhiyun return ecryptfs_removexattr(dentry, inode, name);
1145*4882a593Smuzhiyun }
1146*4882a593Smuzhiyun }
1147*4882a593Smuzhiyun
1148*4882a593Smuzhiyun static const struct xattr_handler ecryptfs_xattr_handler = {
1149*4882a593Smuzhiyun .prefix = "", /* match anything */
1150*4882a593Smuzhiyun .get = ecryptfs_xattr_get,
1151*4882a593Smuzhiyun .set = ecryptfs_xattr_set,
1152*4882a593Smuzhiyun };
1153*4882a593Smuzhiyun
1154*4882a593Smuzhiyun const struct xattr_handler *ecryptfs_xattr_handlers[] = {
1155*4882a593Smuzhiyun &ecryptfs_xattr_handler,
1156*4882a593Smuzhiyun NULL
1157*4882a593Smuzhiyun };
1158