blob: 57bdc686094fd81746c08da8a5e7369ec755b7b0
1 | /* |
2 | * fs/sdcardfs/inode.c |
3 | * |
4 | * Copyright (c) 2013 Samsung Electronics Co. Ltd |
5 | * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, |
6 | * Sunghwan Yun, Sungjong Seo |
7 | * |
8 | * This program has been developed as a stackable file system based on |
9 | * the WrapFS which written by |
10 | * |
11 | * Copyright (c) 1998-2011 Erez Zadok |
12 | * Copyright (c) 2009 Shrikar Archak |
13 | * Copyright (c) 2003-2011 Stony Brook University |
14 | * Copyright (c) 2003-2011 The Research Foundation of SUNY |
15 | * |
16 | * This file is dual licensed. It may be redistributed and/or modified |
17 | * under the terms of the Apache 2.0 License OR version 2 of the GNU |
18 | * General Public License. |
19 | */ |
20 | |
21 | #include "sdcardfs.h" |
22 | #include <linux/fs_struct.h> |
23 | #include <linux/ratelimit.h> |
24 | |
25 | /* Do not directly use this function. Use OVERRIDE_CRED() instead. */ |
26 | const struct cred *override_fsids(struct sdcardfs_sb_info *sbi, |
27 | struct sdcardfs_inode_data *data) |
28 | { |
29 | struct cred *cred; |
30 | const struct cred *old_cred; |
31 | uid_t uid; |
32 | |
33 | cred = prepare_creds(); |
34 | if (!cred) |
35 | return NULL; |
36 | |
37 | if (sbi->options.gid_derivation) { |
38 | if (data->under_obb) |
39 | uid = AID_MEDIA_OBB; |
40 | else |
41 | uid = multiuser_get_uid(data->userid, sbi->options.fs_low_uid); |
42 | } else { |
43 | uid = sbi->options.fs_low_uid; |
44 | } |
45 | cred->fsuid = make_kuid(&init_user_ns, uid); |
46 | cred->fsgid = make_kgid(&init_user_ns, sbi->options.fs_low_gid); |
47 | |
48 | old_cred = override_creds(cred); |
49 | |
50 | return old_cred; |
51 | } |
52 | |
53 | /* Do not directly use this function, use REVERT_CRED() instead. */ |
54 | void revert_fsids(const struct cred *old_cred) |
55 | { |
56 | const struct cred *cur_cred; |
57 | |
58 | cur_cred = current->cred; |
59 | revert_creds(old_cred); |
60 | put_cred(cur_cred); |
61 | } |
62 | |
63 | static int sdcardfs_create(struct inode *dir, struct dentry *dentry, |
64 | umode_t mode, bool want_excl) |
65 | { |
66 | int err; |
67 | struct dentry *lower_dentry; |
68 | struct vfsmount *lower_dentry_mnt; |
69 | struct dentry *lower_parent_dentry = NULL; |
70 | struct path lower_path; |
71 | const struct cred *saved_cred = NULL; |
72 | struct fs_struct *saved_fs; |
73 | struct fs_struct *copied_fs; |
74 | |
75 | if (!check_caller_access_to_name(dir, &dentry->d_name)) { |
76 | err = -EACCES; |
77 | goto out_eacces; |
78 | } |
79 | |
80 | /* save current_cred and override it */ |
81 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir)); |
82 | |
83 | sdcardfs_get_lower_path(dentry, &lower_path); |
84 | lower_dentry = lower_path.dentry; |
85 | lower_dentry_mnt = lower_path.mnt; |
86 | lower_parent_dentry = lock_parent(lower_dentry); |
87 | |
88 | /* set last 16bytes of mode field to 0664 */ |
89 | mode = (mode & S_IFMT) | 00664; |
90 | |
91 | /* temporarily change umask for lower fs write */ |
92 | saved_fs = current->fs; |
93 | copied_fs = copy_fs_struct(current->fs); |
94 | if (!copied_fs) { |
95 | err = -ENOMEM; |
96 | goto out_unlock; |
97 | } |
98 | copied_fs->umask = 0; |
99 | task_lock(current); |
100 | current->fs = copied_fs; |
101 | task_unlock(current); |
102 | err = vfs_create2(lower_dentry_mnt, d_inode(lower_parent_dentry), lower_dentry, mode, want_excl); |
103 | if (err) |
104 | goto out; |
105 | |
106 | err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path, |
107 | SDCARDFS_I(dir)->data->userid); |
108 | if (err) |
109 | goto out; |
110 | fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); |
111 | fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); |
112 | fixup_lower_ownership(dentry, dentry->d_name.name); |
113 | |
114 | out: |
115 | task_lock(current); |
116 | current->fs = saved_fs; |
117 | task_unlock(current); |
118 | free_fs_struct(copied_fs); |
119 | out_unlock: |
120 | unlock_dir(lower_parent_dentry); |
121 | sdcardfs_put_lower_path(dentry, &lower_path); |
122 | REVERT_CRED(saved_cred); |
123 | out_eacces: |
124 | return err; |
125 | } |
126 | |
127 | #if 0 |
128 | static int sdcardfs_link(struct dentry *old_dentry, struct inode *dir, |
129 | struct dentry *new_dentry) |
130 | { |
131 | struct dentry *lower_old_dentry; |
132 | struct dentry *lower_new_dentry; |
133 | struct dentry *lower_dir_dentry; |
134 | u64 file_size_save; |
135 | int err; |
136 | struct path lower_old_path, lower_new_path; |
137 | |
138 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb)); |
139 | |
140 | file_size_save = i_size_read(d_inode(old_dentry)); |
141 | sdcardfs_get_lower_path(old_dentry, &lower_old_path); |
142 | sdcardfs_get_lower_path(new_dentry, &lower_new_path); |
143 | lower_old_dentry = lower_old_path.dentry; |
144 | lower_new_dentry = lower_new_path.dentry; |
145 | lower_dir_dentry = lock_parent(lower_new_dentry); |
146 | |
147 | err = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry), |
148 | lower_new_dentry, NULL); |
149 | if (err || !d_inode(lower_new_dentry)) |
150 | goto out; |
151 | |
152 | err = sdcardfs_interpose(new_dentry, dir->i_sb, &lower_new_path); |
153 | if (err) |
154 | goto out; |
155 | fsstack_copy_attr_times(dir, d_inode(lower_new_dentry)); |
156 | fsstack_copy_inode_size(dir, d_inode(lower_new_dentry)); |
157 | set_nlink(d_inode(old_dentry), |
158 | sdcardfs_lower_inode(d_inode(old_dentry))->i_nlink); |
159 | i_size_write(d_inode(new_dentry), file_size_save); |
160 | out: |
161 | unlock_dir(lower_dir_dentry); |
162 | sdcardfs_put_lower_path(old_dentry, &lower_old_path); |
163 | sdcardfs_put_lower_path(new_dentry, &lower_new_path); |
164 | REVERT_CRED(); |
165 | return err; |
166 | } |
167 | #endif |
168 | |
169 | static int sdcardfs_unlink(struct inode *dir, struct dentry *dentry) |
170 | { |
171 | int err; |
172 | struct dentry *lower_dentry; |
173 | struct vfsmount *lower_mnt; |
174 | struct inode *lower_dir_inode = sdcardfs_lower_inode(dir); |
175 | struct dentry *lower_dir_dentry; |
176 | struct path lower_path; |
177 | const struct cred *saved_cred = NULL; |
178 | |
179 | if (!check_caller_access_to_name(dir, &dentry->d_name)) { |
180 | err = -EACCES; |
181 | goto out_eacces; |
182 | } |
183 | |
184 | /* save current_cred and override it */ |
185 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir)); |
186 | |
187 | sdcardfs_get_lower_path(dentry, &lower_path); |
188 | lower_dentry = lower_path.dentry; |
189 | lower_mnt = lower_path.mnt; |
190 | dget(lower_dentry); |
191 | lower_dir_dentry = lock_parent(lower_dentry); |
192 | |
193 | err = vfs_unlink2(lower_mnt, lower_dir_inode, lower_dentry, NULL); |
194 | |
195 | /* |
196 | * Note: unlinking on top of NFS can cause silly-renamed files. |
197 | * Trying to delete such files results in EBUSY from NFS |
198 | * below. Silly-renamed files will get deleted by NFS later on, so |
199 | * we just need to detect them here and treat such EBUSY errors as |
200 | * if the upper file was successfully deleted. |
201 | */ |
202 | if (err == -EBUSY && lower_dentry->d_flags & DCACHE_NFSFS_RENAMED) |
203 | err = 0; |
204 | if (err) |
205 | goto out; |
206 | fsstack_copy_attr_times(dir, lower_dir_inode); |
207 | fsstack_copy_inode_size(dir, lower_dir_inode); |
208 | set_nlink(d_inode(dentry), |
209 | sdcardfs_lower_inode(d_inode(dentry))->i_nlink); |
210 | d_inode(dentry)->i_ctime = dir->i_ctime; |
211 | d_drop(dentry); /* this is needed, else LTP fails (VFS won't do it) */ |
212 | out: |
213 | unlock_dir(lower_dir_dentry); |
214 | dput(lower_dentry); |
215 | sdcardfs_put_lower_path(dentry, &lower_path); |
216 | REVERT_CRED(saved_cred); |
217 | out_eacces: |
218 | return err; |
219 | } |
220 | |
221 | #if 0 |
222 | static int sdcardfs_symlink(struct inode *dir, struct dentry *dentry, |
223 | const char *symname) |
224 | { |
225 | int err; |
226 | struct dentry *lower_dentry; |
227 | struct dentry *lower_parent_dentry = NULL; |
228 | struct path lower_path; |
229 | |
230 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb)); |
231 | |
232 | sdcardfs_get_lower_path(dentry, &lower_path); |
233 | lower_dentry = lower_path.dentry; |
234 | lower_parent_dentry = lock_parent(lower_dentry); |
235 | |
236 | err = vfs_symlink(d_inode(lower_parent_dentry), lower_dentry, symname); |
237 | if (err) |
238 | goto out; |
239 | err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path); |
240 | if (err) |
241 | goto out; |
242 | fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); |
243 | fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); |
244 | |
245 | out: |
246 | unlock_dir(lower_parent_dentry); |
247 | sdcardfs_put_lower_path(dentry, &lower_path); |
248 | REVERT_CRED(); |
249 | return err; |
250 | } |
251 | #endif |
252 | |
253 | static int touch(char *abs_path, mode_t mode) |
254 | { |
255 | struct file *filp = filp_open(abs_path, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, mode); |
256 | |
257 | if (IS_ERR(filp)) { |
258 | if (PTR_ERR(filp) == -EEXIST) { |
259 | return 0; |
260 | } else { |
261 | pr_err("sdcardfs: failed to open(%s): %ld\n", |
262 | abs_path, PTR_ERR(filp)); |
263 | return PTR_ERR(filp); |
264 | } |
265 | } |
266 | filp_close(filp, current->files); |
267 | return 0; |
268 | } |
269 | |
270 | static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
271 | { |
272 | int err; |
273 | int make_nomedia_in_obb = 0; |
274 | struct dentry *lower_dentry; |
275 | struct vfsmount *lower_mnt; |
276 | struct dentry *lower_parent_dentry = NULL; |
277 | struct dentry *parent_dentry = NULL; |
278 | struct path lower_path; |
279 | struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); |
280 | const struct cred *saved_cred = NULL; |
281 | struct sdcardfs_inode_data *pd = SDCARDFS_I(dir)->data; |
282 | int touch_err = 0; |
283 | struct fs_struct *saved_fs; |
284 | struct fs_struct *copied_fs; |
285 | struct qstr q_obb = QSTR_LITERAL("obb"); |
286 | struct qstr q_data = QSTR_LITERAL("data"); |
287 | |
288 | if (!check_caller_access_to_name(dir, &dentry->d_name)) { |
289 | err = -EACCES; |
290 | goto out_eacces; |
291 | } |
292 | |
293 | /* save current_cred and override it */ |
294 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir)); |
295 | |
296 | /* check disk space */ |
297 | parent_dentry = dget_parent(dentry); |
298 | if (!check_min_free_space(parent_dentry, 0, 1)) { |
299 | pr_err("sdcardfs: No minimum free space.\n"); |
300 | err = -ENOSPC; |
301 | dput(parent_dentry); |
302 | goto out_revert; |
303 | } |
304 | dput(parent_dentry); |
305 | |
306 | /* the lower_dentry is negative here */ |
307 | sdcardfs_get_lower_path(dentry, &lower_path); |
308 | lower_dentry = lower_path.dentry; |
309 | lower_mnt = lower_path.mnt; |
310 | lower_parent_dentry = lock_parent(lower_dentry); |
311 | |
312 | /* set last 16bytes of mode field to 0775 */ |
313 | mode = (mode & S_IFMT) | 00775; |
314 | |
315 | /* temporarily change umask for lower fs write */ |
316 | saved_fs = current->fs; |
317 | copied_fs = copy_fs_struct(current->fs); |
318 | if (!copied_fs) { |
319 | err = -ENOMEM; |
320 | unlock_dir(lower_parent_dentry); |
321 | goto out_unlock; |
322 | } |
323 | copied_fs->umask = 0; |
324 | task_lock(current); |
325 | current->fs = copied_fs; |
326 | task_unlock(current); |
327 | err = vfs_mkdir2(lower_mnt, d_inode(lower_parent_dentry), lower_dentry, mode); |
328 | |
329 | if (err) { |
330 | unlock_dir(lower_parent_dentry); |
331 | goto out; |
332 | } |
333 | |
334 | /* if it is a local obb dentry, setup it with the base obbpath */ |
335 | if (need_graft_path(dentry)) { |
336 | |
337 | err = setup_obb_dentry(dentry, &lower_path); |
338 | if (err) { |
339 | /* if the sbi->obbpath is not available, the lower_path won't be |
340 | * changed by setup_obb_dentry() but the lower path is saved to |
341 | * its orig_path. this dentry will be revalidated later. |
342 | * but now, the lower_path should be NULL |
343 | */ |
344 | sdcardfs_put_reset_lower_path(dentry); |
345 | |
346 | /* the newly created lower path which saved to its orig_path or |
347 | * the lower_path is the base obbpath. |
348 | * therefore, an additional path_get is required |
349 | */ |
350 | path_get(&lower_path); |
351 | } else |
352 | make_nomedia_in_obb = 1; |
353 | } |
354 | |
355 | err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path, pd->userid); |
356 | if (err) { |
357 | unlock_dir(lower_parent_dentry); |
358 | goto out; |
359 | } |
360 | |
361 | fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); |
362 | fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); |
363 | /* update number of links on parent directory */ |
364 | set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink); |
365 | fixup_lower_ownership(dentry, dentry->d_name.name); |
366 | unlock_dir(lower_parent_dentry); |
367 | if ((!sbi->options.multiuser) && (qstr_case_eq(&dentry->d_name, &q_obb)) |
368 | && (pd->perm == PERM_ANDROID) && (pd->userid == 0)) |
369 | make_nomedia_in_obb = 1; |
370 | |
371 | /* When creating /Android/data and /Android/obb, mark them as .nomedia */ |
372 | if (make_nomedia_in_obb || |
373 | ((pd->perm == PERM_ANDROID) |
374 | && (qstr_case_eq(&dentry->d_name, &q_data)))) { |
375 | REVERT_CRED(saved_cred); |
376 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(d_inode(dentry))); |
377 | set_fs_pwd(current->fs, &lower_path); |
378 | touch_err = touch(".nomedia", 0664); |
379 | if (touch_err) { |
380 | pr_err("sdcardfs: failed to create .nomedia in %s: %d\n", |
381 | lower_path.dentry->d_name.name, touch_err); |
382 | goto out; |
383 | } |
384 | } |
385 | out: |
386 | task_lock(current); |
387 | current->fs = saved_fs; |
388 | task_unlock(current); |
389 | |
390 | free_fs_struct(copied_fs); |
391 | out_unlock: |
392 | sdcardfs_put_lower_path(dentry, &lower_path); |
393 | out_revert: |
394 | REVERT_CRED(saved_cred); |
395 | out_eacces: |
396 | return err; |
397 | } |
398 | |
399 | static int sdcardfs_rmdir(struct inode *dir, struct dentry *dentry) |
400 | { |
401 | struct dentry *lower_dentry; |
402 | struct dentry *lower_dir_dentry; |
403 | struct vfsmount *lower_mnt; |
404 | int err; |
405 | struct path lower_path; |
406 | const struct cred *saved_cred = NULL; |
407 | |
408 | if (!check_caller_access_to_name(dir, &dentry->d_name)) { |
409 | err = -EACCES; |
410 | goto out_eacces; |
411 | } |
412 | |
413 | /* save current_cred and override it */ |
414 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir)); |
415 | |
416 | /* sdcardfs_get_real_lower(): in case of remove an user's obb dentry |
417 | * the dentry on the original path should be deleted. |
418 | */ |
419 | sdcardfs_get_real_lower(dentry, &lower_path); |
420 | |
421 | lower_dentry = lower_path.dentry; |
422 | lower_mnt = lower_path.mnt; |
423 | lower_dir_dentry = lock_parent(lower_dentry); |
424 | |
425 | err = vfs_rmdir2(lower_mnt, d_inode(lower_dir_dentry), lower_dentry); |
426 | if (err) |
427 | goto out; |
428 | |
429 | d_drop(dentry); /* drop our dentry on success (why not VFS's job?) */ |
430 | if (d_inode(dentry)) |
431 | clear_nlink(d_inode(dentry)); |
432 | fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); |
433 | fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); |
434 | set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); |
435 | |
436 | out: |
437 | unlock_dir(lower_dir_dentry); |
438 | sdcardfs_put_real_lower(dentry, &lower_path); |
439 | REVERT_CRED(saved_cred); |
440 | out_eacces: |
441 | return err; |
442 | } |
443 | |
444 | #if 0 |
445 | static int sdcardfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, |
446 | dev_t dev) |
447 | { |
448 | int err; |
449 | struct dentry *lower_dentry; |
450 | struct dentry *lower_parent_dentry = NULL; |
451 | struct path lower_path; |
452 | |
453 | OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb)); |
454 | |
455 | sdcardfs_get_lower_path(dentry, &lower_path); |
456 | lower_dentry = lower_path.dentry; |
457 | lower_parent_dentry = lock_parent(lower_dentry); |
458 | |
459 | err = vfs_mknod(d_inode(lower_parent_dentry), lower_dentry, mode, dev); |
460 | if (err) |
461 | goto out; |
462 | |
463 | err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path); |
464 | if (err) |
465 | goto out; |
466 | fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); |
467 | fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); |
468 | |
469 | out: |
470 | unlock_dir(lower_parent_dentry); |
471 | sdcardfs_put_lower_path(dentry, &lower_path); |
472 | REVERT_CRED(); |
473 | return err; |
474 | } |
475 | #endif |
476 | |
477 | /* |
478 | * The locking rules in sdcardfs_rename are complex. We could use a simpler |
479 | * superblock-level name-space lock for renames and copy-ups. |
480 | */ |
481 | static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
482 | struct inode *new_dir, struct dentry *new_dentry, |
483 | unsigned int flags) |
484 | { |
485 | int err = 0; |
486 | struct dentry *lower_old_dentry = NULL; |
487 | struct dentry *lower_new_dentry = NULL; |
488 | struct dentry *lower_old_dir_dentry = NULL; |
489 | struct dentry *lower_new_dir_dentry = NULL; |
490 | struct vfsmount *lower_mnt = NULL; |
491 | struct dentry *trap = NULL; |
492 | struct path lower_old_path, lower_new_path; |
493 | const struct cred *saved_cred = NULL; |
494 | |
495 | if (flags) |
496 | return -EINVAL; |
497 | |
498 | if (!check_caller_access_to_name(old_dir, &old_dentry->d_name) || |
499 | !check_caller_access_to_name(new_dir, &new_dentry->d_name)) { |
500 | err = -EACCES; |
501 | goto out_eacces; |
502 | } |
503 | |
504 | /* save current_cred and override it */ |
505 | OVERRIDE_CRED(SDCARDFS_SB(old_dir->i_sb), saved_cred, SDCARDFS_I(new_dir)); |
506 | |
507 | sdcardfs_get_real_lower(old_dentry, &lower_old_path); |
508 | sdcardfs_get_lower_path(new_dentry, &lower_new_path); |
509 | lower_old_dentry = lower_old_path.dentry; |
510 | lower_new_dentry = lower_new_path.dentry; |
511 | lower_mnt = lower_old_path.mnt; |
512 | lower_old_dir_dentry = dget_parent(lower_old_dentry); |
513 | lower_new_dir_dentry = dget_parent(lower_new_dentry); |
514 | |
515 | trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
516 | /* source should not be ancestor of target */ |
517 | if (trap == lower_old_dentry) { |
518 | err = -EINVAL; |
519 | goto out; |
520 | } |
521 | /* target should not be ancestor of source */ |
522 | if (trap == lower_new_dentry) { |
523 | err = -ENOTEMPTY; |
524 | goto out; |
525 | } |
526 | |
527 | err = vfs_rename2(lower_mnt, |
528 | d_inode(lower_old_dir_dentry), lower_old_dentry, |
529 | d_inode(lower_new_dir_dentry), lower_new_dentry, |
530 | NULL, 0); |
531 | if (err) |
532 | goto out; |
533 | |
534 | /* Copy attrs from lower dir, but i_uid/i_gid */ |
535 | sdcardfs_copy_and_fix_attrs(new_dir, d_inode(lower_new_dir_dentry)); |
536 | fsstack_copy_inode_size(new_dir, d_inode(lower_new_dir_dentry)); |
537 | |
538 | if (new_dir != old_dir) { |
539 | sdcardfs_copy_and_fix_attrs(old_dir, d_inode(lower_old_dir_dentry)); |
540 | fsstack_copy_inode_size(old_dir, d_inode(lower_old_dir_dentry)); |
541 | } |
542 | get_derived_permission_new(new_dentry->d_parent, old_dentry, &new_dentry->d_name); |
543 | fixup_tmp_permissions(d_inode(old_dentry)); |
544 | fixup_lower_ownership(old_dentry, new_dentry->d_name.name); |
545 | d_invalidate(old_dentry); /* Can't fixup ownership recursively :( */ |
546 | out: |
547 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
548 | dput(lower_old_dir_dentry); |
549 | dput(lower_new_dir_dentry); |
550 | sdcardfs_put_real_lower(old_dentry, &lower_old_path); |
551 | sdcardfs_put_lower_path(new_dentry, &lower_new_path); |
552 | REVERT_CRED(saved_cred); |
553 | out_eacces: |
554 | return err; |
555 | } |
556 | |
557 | #if 0 |
558 | static int sdcardfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) |
559 | { |
560 | int err; |
561 | struct dentry *lower_dentry; |
562 | struct path lower_path; |
563 | /* XXX readlink does not requires overriding credential */ |
564 | |
565 | sdcardfs_get_lower_path(dentry, &lower_path); |
566 | lower_dentry = lower_path.dentry; |
567 | if (!d_inode(lower_dentry)->i_op || |
568 | !d_inode(lower_dentry)->i_op->readlink) { |
569 | err = -EINVAL; |
570 | goto out; |
571 | } |
572 | |
573 | err = d_inode(lower_dentry)->i_op->readlink(lower_dentry, |
574 | buf, bufsiz); |
575 | if (err < 0) |
576 | goto out; |
577 | fsstack_copy_attr_atime(d_inode(dentry), d_inode(lower_dentry)); |
578 | |
579 | out: |
580 | sdcardfs_put_lower_path(dentry, &lower_path); |
581 | return err; |
582 | } |
583 | #endif |
584 | |
585 | #if 0 |
586 | static const char *sdcardfs_follow_link(struct dentry *dentry, void **cookie) |
587 | { |
588 | char *buf; |
589 | int len = PAGE_SIZE, err; |
590 | mm_segment_t old_fs; |
591 | |
592 | /* This is freed by the put_link method assuming a successful call. */ |
593 | buf = kmalloc(len, GFP_KERNEL); |
594 | if (!buf) { |
595 | buf = ERR_PTR(-ENOMEM); |
596 | return buf; |
597 | } |
598 | |
599 | /* read the symlink, and then we will follow it */ |
600 | old_fs = get_fs(); |
601 | set_fs(KERNEL_DS); |
602 | err = sdcardfs_readlink(dentry, buf, len); |
603 | set_fs(old_fs); |
604 | if (err < 0) { |
605 | kfree(buf); |
606 | buf = ERR_PTR(err); |
607 | } else { |
608 | buf[err] = '\0'; |
609 | } |
610 | return *cookie = buf; |
611 | } |
612 | #endif |
613 | |
614 | static int sdcardfs_permission_wrn(struct inode *inode, int mask) |
615 | { |
616 | WARN_RATELIMIT(1, "sdcardfs does not support permission. Use permission2.\n"); |
617 | return -EINVAL; |
618 | } |
619 | |
620 | void copy_attrs(struct inode *dest, const struct inode *src) |
621 | { |
622 | dest->i_mode = src->i_mode; |
623 | dest->i_uid = src->i_uid; |
624 | dest->i_gid = src->i_gid; |
625 | dest->i_rdev = src->i_rdev; |
626 | dest->i_atime = src->i_atime; |
627 | dest->i_mtime = src->i_mtime; |
628 | dest->i_ctime = src->i_ctime; |
629 | dest->i_blkbits = src->i_blkbits; |
630 | dest->i_flags = src->i_flags; |
631 | #ifdef CONFIG_FS_POSIX_ACL |
632 | dest->i_acl = src->i_acl; |
633 | #endif |
634 | #ifdef CONFIG_SECURITY |
635 | dest->i_security = src->i_security; |
636 | #endif |
637 | } |
638 | |
639 | static int sdcardfs_permission(struct vfsmount *mnt, struct inode *inode, int mask) |
640 | { |
641 | int err; |
642 | struct inode tmp; |
643 | struct sdcardfs_inode_data *top = top_data_get(SDCARDFS_I(inode)); |
644 | |
645 | if (IS_ERR(mnt)) |
646 | return PTR_ERR(mnt); |
647 | if (!top) |
648 | return -EINVAL; |
649 | |
650 | /* |
651 | * Permission check on sdcardfs inode. |
652 | * Calling process should have AID_SDCARD_RW permission |
653 | * Since generic_permission only needs i_mode, i_uid, |
654 | * i_gid, and i_sb, we can create a fake inode to pass |
655 | * this information down in. |
656 | * |
657 | * The underlying code may attempt to take locks in some |
658 | * cases for features we're not using, but if that changes, |
659 | * locks must be dealt with to avoid undefined behavior. |
660 | */ |
661 | copy_attrs(&tmp, inode); |
662 | tmp.i_uid = make_kuid(&init_user_ns, top->d_uid); |
663 | tmp.i_gid = make_kgid(&init_user_ns, get_gid(mnt, inode->i_sb, top)); |
664 | tmp.i_mode = (inode->i_mode & S_IFMT) |
665 | | get_mode(mnt, SDCARDFS_I(inode), top); |
666 | data_put(top); |
667 | tmp.i_sb = inode->i_sb; |
668 | if (IS_POSIXACL(inode)) |
669 | pr_warn("%s: This may be undefined behavior...\n", __func__); |
670 | err = generic_permission(&tmp, mask); |
671 | /* XXX |
672 | * Original sdcardfs code calls inode_permission(lower_inode,.. ) |
673 | * for checking inode permission. But doing such things here seems |
674 | * duplicated work, because the functions called after this func, |
675 | * such as vfs_create, vfs_unlink, vfs_rename, and etc, |
676 | * does exactly same thing, i.e., they calls inode_permission(). |
677 | * So we just let they do the things. |
678 | * If there are any security hole, just uncomment following if block. |
679 | */ |
680 | #if 0 |
681 | if (!err) { |
682 | /* |
683 | * Permission check on lower_inode(=EXT4). |
684 | * we check it with AID_MEDIA_RW permission |
685 | */ |
686 | struct inode *lower_inode; |
687 | |
688 | OVERRIDE_CRED(SDCARDFS_SB(inode->sb)); |
689 | |
690 | lower_inode = sdcardfs_lower_inode(inode); |
691 | err = inode_permission(lower_inode, mask); |
692 | |
693 | REVERT_CRED(); |
694 | } |
695 | #endif |
696 | return err; |
697 | |
698 | } |
699 | |
700 | static int sdcardfs_setattr_wrn(struct dentry *dentry, struct iattr *ia) |
701 | { |
702 | WARN_RATELIMIT(1, "sdcardfs does not support setattr. User setattr2.\n"); |
703 | return -EINVAL; |
704 | } |
705 | |
706 | #ifdef CONFIG_AMLOGIC_VMAP |
707 | /* a save stack version */ |
708 | static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, |
709 | struct iattr *ia) |
710 | { |
711 | int err; |
712 | struct dentry *lower_dentry; |
713 | struct vfsmount *lower_mnt; |
714 | struct inode *inode; |
715 | struct inode *lower_inode; |
716 | struct path lower_path; |
717 | struct iattr lower_ia; |
718 | struct dentry *parent; |
719 | struct inode *tmp; |
720 | struct dentry *tmp_d; |
721 | struct sdcardfs_inode_data *top; |
722 | |
723 | const struct cred *saved_cred = NULL; |
724 | |
725 | inode = d_inode(dentry); |
726 | top = top_data_get(SDCARDFS_I(inode)); |
727 | |
728 | if (!top) |
729 | return -EINVAL; |
730 | |
731 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
732 | if (!tmp) |
733 | return -ENOMEM; |
734 | |
735 | tmp_d = kzalloc(sizeof(*tmp_d), GFP_KERNEL); |
736 | if (!tmp_d) { |
737 | kfree(tmp); |
738 | return -ENOMEM; |
739 | } |
740 | /* |
741 | * Permission check on sdcardfs inode. |
742 | * Calling process should have AID_SDCARD_RW permission |
743 | * Since generic_permission only needs i_mode, i_uid, |
744 | * i_gid, and i_sb, we can create a fake inode to pass |
745 | * this information down in. |
746 | * |
747 | * The underlying code may attempt to take locks in some |
748 | * cases for features we're not using, but if that changes, |
749 | * locks must be dealt with to avoid undefined behavior. |
750 | * |
751 | */ |
752 | copy_attrs(tmp, inode); |
753 | tmp->i_uid = make_kuid(&init_user_ns, top->d_uid); |
754 | tmp->i_gid = make_kgid(&init_user_ns, get_gid(mnt, dentry->d_sb, top)); |
755 | tmp->i_mode = (inode->i_mode & S_IFMT) |
756 | | get_mode(mnt, SDCARDFS_I(inode), top); |
757 | tmp->i_size = i_size_read(inode); |
758 | data_put(top); |
759 | tmp->i_sb = inode->i_sb; |
760 | tmp_d->d_inode = tmp; |
761 | |
762 | /* |
763 | * Check if user has permission to change dentry. We don't check if |
764 | * this user can change the lower inode: that should happen when |
765 | * calling notify_change on the lower inode. |
766 | */ |
767 | /* prepare our own lower struct iattr (with the lower file) */ |
768 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
769 | /* Allow touch updating timestamps. A previous permission check ensures |
770 | * we have write access. Changes to mode, owner, and group are ignored |
771 | */ |
772 | ia->ia_valid |= ATTR_FORCE; |
773 | err = setattr_prepare(tmp_d, ia); |
774 | |
775 | if (!err) { |
776 | /* check the Android group ID */ |
777 | parent = dget_parent(dentry); |
778 | if (!check_caller_access_to_name(d_inode(parent), |
779 | &dentry->d_name)) |
780 | err = -EACCES; |
781 | dput(parent); |
782 | } |
783 | |
784 | if (err) |
785 | goto out_err; |
786 | |
787 | /* save current_cred and override it */ |
788 | OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred, SDCARDFS_I(inode)); |
789 | |
790 | sdcardfs_get_lower_path(dentry, &lower_path); |
791 | lower_dentry = lower_path.dentry; |
792 | lower_mnt = lower_path.mnt; |
793 | lower_inode = sdcardfs_lower_inode(inode); |
794 | |
795 | if (ia->ia_valid & ATTR_FILE) |
796 | lower_ia.ia_file = sdcardfs_lower_file(ia->ia_file); |
797 | |
798 | lower_ia.ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE); |
799 | |
800 | /* |
801 | * If shrinking, first truncate upper level to cancel writing dirty |
802 | * pages beyond the new eof; and also if its' maxbytes is more |
803 | * limiting (fail with -EFBIG before making any change to the lower |
804 | * level). There is no need to vmtruncate the upper level |
805 | * afterwards in the other cases: we fsstack_copy_inode_size from |
806 | * the lower level. |
807 | */ |
808 | if (ia->ia_valid & ATTR_SIZE) { |
809 | err = inode_newsize_ok(tmp, ia->ia_size); |
810 | if (err) |
811 | goto out; |
812 | truncate_setsize(inode, ia->ia_size); |
813 | } |
814 | |
815 | /* |
816 | * mode change is for clearing setuid/setgid bits. Allow lower fs |
817 | * to interpret this in its own way. |
818 | */ |
819 | if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) |
820 | lower_ia.ia_valid &= ~ATTR_MODE; |
821 | |
822 | /* notify the (possibly copied-up) lower inode */ |
823 | /* |
824 | * Note: we use d_inode(lower_dentry), because lower_inode may be |
825 | * unlinked (no inode->i_sb and i_ino==0. This happens if someone |
826 | * tries to open(), unlink(), then ftruncate() a file. |
827 | */ |
828 | inode_lock(d_inode(lower_dentry)); |
829 | err = notify_change2(lower_mnt, lower_dentry, &lower_ia, |
830 | NULL); |
831 | inode_unlock(d_inode(lower_dentry)); |
832 | if (err) |
833 | goto out; |
834 | |
835 | /* get attributes from the lower inode and update derived permissions */ |
836 | sdcardfs_copy_and_fix_attrs(inode, lower_inode); |
837 | |
838 | /* |
839 | * Not running fsstack_copy_inode_size(inode, lower_inode), because |
840 | * VFS should update our inode size, and notify_change on |
841 | * lower_inode should update its size. |
842 | */ |
843 | |
844 | out: |
845 | sdcardfs_put_lower_path(dentry, &lower_path); |
846 | REVERT_CRED(saved_cred); |
847 | out_err: |
848 | kfree(tmp); |
849 | kfree(tmp_d); |
850 | return err; |
851 | } |
852 | #else |
853 | static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct iattr *ia) |
854 | { |
855 | int err; |
856 | struct dentry *lower_dentry; |
857 | struct vfsmount *lower_mnt; |
858 | struct inode *inode; |
859 | struct inode *lower_inode; |
860 | struct path lower_path; |
861 | struct iattr lower_ia; |
862 | struct dentry *parent; |
863 | struct inode tmp; |
864 | struct dentry tmp_d; |
865 | struct sdcardfs_inode_data *top; |
866 | |
867 | const struct cred *saved_cred = NULL; |
868 | |
869 | inode = d_inode(dentry); |
870 | top = top_data_get(SDCARDFS_I(inode)); |
871 | |
872 | if (!top) |
873 | return -EINVAL; |
874 | |
875 | /* |
876 | * Permission check on sdcardfs inode. |
877 | * Calling process should have AID_SDCARD_RW permission |
878 | * Since generic_permission only needs i_mode, i_uid, |
879 | * i_gid, and i_sb, we can create a fake inode to pass |
880 | * this information down in. |
881 | * |
882 | * The underlying code may attempt to take locks in some |
883 | * cases for features we're not using, but if that changes, |
884 | * locks must be dealt with to avoid undefined behavior. |
885 | * |
886 | */ |
887 | copy_attrs(&tmp, inode); |
888 | tmp.i_uid = make_kuid(&init_user_ns, top->d_uid); |
889 | tmp.i_gid = make_kgid(&init_user_ns, get_gid(mnt, dentry->d_sb, top)); |
890 | tmp.i_mode = (inode->i_mode & S_IFMT) |
891 | | get_mode(mnt, SDCARDFS_I(inode), top); |
892 | tmp.i_size = i_size_read(inode); |
893 | data_put(top); |
894 | tmp.i_sb = inode->i_sb; |
895 | tmp_d.d_inode = &tmp; |
896 | |
897 | /* |
898 | * Check if user has permission to change dentry. We don't check if |
899 | * this user can change the lower inode: that should happen when |
900 | * calling notify_change on the lower inode. |
901 | */ |
902 | /* prepare our own lower struct iattr (with the lower file) */ |
903 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
904 | /* Allow touch updating timestamps. A previous permission check ensures |
905 | * we have write access. Changes to mode, owner, and group are ignored |
906 | */ |
907 | ia->ia_valid |= ATTR_FORCE; |
908 | err = setattr_prepare(&tmp_d, ia); |
909 | |
910 | if (!err) { |
911 | /* check the Android group ID */ |
912 | parent = dget_parent(dentry); |
913 | if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) |
914 | err = -EACCES; |
915 | dput(parent); |
916 | } |
917 | |
918 | if (err) |
919 | goto out_err; |
920 | |
921 | /* save current_cred and override it */ |
922 | OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred, SDCARDFS_I(inode)); |
923 | |
924 | sdcardfs_get_lower_path(dentry, &lower_path); |
925 | lower_dentry = lower_path.dentry; |
926 | lower_mnt = lower_path.mnt; |
927 | lower_inode = sdcardfs_lower_inode(inode); |
928 | |
929 | if (ia->ia_valid & ATTR_FILE) |
930 | lower_ia.ia_file = sdcardfs_lower_file(ia->ia_file); |
931 | |
932 | lower_ia.ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE); |
933 | |
934 | /* |
935 | * If shrinking, first truncate upper level to cancel writing dirty |
936 | * pages beyond the new eof; and also if its' maxbytes is more |
937 | * limiting (fail with -EFBIG before making any change to the lower |
938 | * level). There is no need to vmtruncate the upper level |
939 | * afterwards in the other cases: we fsstack_copy_inode_size from |
940 | * the lower level. |
941 | */ |
942 | if (ia->ia_valid & ATTR_SIZE) { |
943 | err = inode_newsize_ok(&tmp, ia->ia_size); |
944 | if (err) { |
945 | goto out; |
946 | } |
947 | truncate_setsize(inode, ia->ia_size); |
948 | } |
949 | |
950 | /* |
951 | * mode change is for clearing setuid/setgid bits. Allow lower fs |
952 | * to interpret this in its own way. |
953 | */ |
954 | if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) |
955 | lower_ia.ia_valid &= ~ATTR_MODE; |
956 | |
957 | /* notify the (possibly copied-up) lower inode */ |
958 | /* |
959 | * Note: we use d_inode(lower_dentry), because lower_inode may be |
960 | * unlinked (no inode->i_sb and i_ino==0. This happens if someone |
961 | * tries to open(), unlink(), then ftruncate() a file. |
962 | */ |
963 | inode_lock(d_inode(lower_dentry)); |
964 | err = notify_change2(lower_mnt, lower_dentry, &lower_ia, /* note: lower_ia */ |
965 | NULL); |
966 | inode_unlock(d_inode(lower_dentry)); |
967 | if (err) |
968 | goto out; |
969 | |
970 | /* get attributes from the lower inode and update derived permissions */ |
971 | sdcardfs_copy_and_fix_attrs(inode, lower_inode); |
972 | |
973 | /* |
974 | * Not running fsstack_copy_inode_size(inode, lower_inode), because |
975 | * VFS should update our inode size, and notify_change on |
976 | * lower_inode should update its size. |
977 | */ |
978 | |
979 | out: |
980 | sdcardfs_put_lower_path(dentry, &lower_path); |
981 | REVERT_CRED(saved_cred); |
982 | out_err: |
983 | return err; |
984 | } |
985 | #endif |
986 | |
987 | static int sdcardfs_fillattr(struct vfsmount *mnt, struct inode *inode, |
988 | struct kstat *lower_stat, struct kstat *stat) |
989 | { |
990 | struct sdcardfs_inode_info *info = SDCARDFS_I(inode); |
991 | struct sdcardfs_inode_data *top = top_data_get(info); |
992 | struct super_block *sb = inode->i_sb; |
993 | |
994 | if (!top) |
995 | return -EINVAL; |
996 | |
997 | stat->dev = inode->i_sb->s_dev; |
998 | stat->ino = inode->i_ino; |
999 | stat->mode = (inode->i_mode & S_IFMT) | get_mode(mnt, info, top); |
1000 | stat->nlink = inode->i_nlink; |
1001 | stat->uid = make_kuid(&init_user_ns, top->d_uid); |
1002 | stat->gid = make_kgid(&init_user_ns, get_gid(mnt, sb, top)); |
1003 | stat->rdev = inode->i_rdev; |
1004 | stat->size = lower_stat->size; |
1005 | stat->atime = lower_stat->atime; |
1006 | stat->mtime = lower_stat->mtime; |
1007 | stat->ctime = lower_stat->ctime; |
1008 | stat->blksize = lower_stat->blksize; |
1009 | stat->blocks = lower_stat->blocks; |
1010 | data_put(top); |
1011 | return 0; |
1012 | } |
1013 | |
1014 | static int sdcardfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1015 | struct kstat *stat) |
1016 | { |
1017 | struct kstat lower_stat; |
1018 | struct path lower_path; |
1019 | struct dentry *parent; |
1020 | int err; |
1021 | |
1022 | parent = dget_parent(dentry); |
1023 | if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) { |
1024 | dput(parent); |
1025 | return -EACCES; |
1026 | } |
1027 | dput(parent); |
1028 | |
1029 | sdcardfs_get_lower_path(dentry, &lower_path); |
1030 | err = vfs_getattr(&lower_path, &lower_stat); |
1031 | if (err) |
1032 | goto out; |
1033 | sdcardfs_copy_and_fix_attrs(d_inode(dentry), |
1034 | d_inode(lower_path.dentry)); |
1035 | err = sdcardfs_fillattr(mnt, d_inode(dentry), &lower_stat, stat); |
1036 | out: |
1037 | sdcardfs_put_lower_path(dentry, &lower_path); |
1038 | return err; |
1039 | } |
1040 | |
1041 | const struct inode_operations sdcardfs_symlink_iops = { |
1042 | .permission2 = sdcardfs_permission, |
1043 | .setattr2 = sdcardfs_setattr, |
1044 | /* XXX Following operations are implemented, |
1045 | * but FUSE(sdcard) or FAT does not support them |
1046 | * These methods are *NOT* perfectly tested. |
1047 | .readlink = sdcardfs_readlink, |
1048 | .follow_link = sdcardfs_follow_link, |
1049 | .put_link = kfree_put_link, |
1050 | */ |
1051 | }; |
1052 | |
1053 | const struct inode_operations sdcardfs_dir_iops = { |
1054 | .create = sdcardfs_create, |
1055 | .lookup = sdcardfs_lookup, |
1056 | .permission = sdcardfs_permission_wrn, |
1057 | .permission2 = sdcardfs_permission, |
1058 | .unlink = sdcardfs_unlink, |
1059 | .mkdir = sdcardfs_mkdir, |
1060 | .rmdir = sdcardfs_rmdir, |
1061 | .rename = sdcardfs_rename, |
1062 | .setattr = sdcardfs_setattr_wrn, |
1063 | .setattr2 = sdcardfs_setattr, |
1064 | .getattr = sdcardfs_getattr, |
1065 | /* XXX Following operations are implemented, |
1066 | * but FUSE(sdcard) or FAT does not support them |
1067 | * These methods are *NOT* perfectly tested. |
1068 | .symlink = sdcardfs_symlink, |
1069 | .link = sdcardfs_link, |
1070 | .mknod = sdcardfs_mknod, |
1071 | */ |
1072 | }; |
1073 | |
1074 | const struct inode_operations sdcardfs_main_iops = { |
1075 | .permission = sdcardfs_permission_wrn, |
1076 | .permission2 = sdcardfs_permission, |
1077 | .setattr = sdcardfs_setattr_wrn, |
1078 | .setattr2 = sdcardfs_setattr, |
1079 | .getattr = sdcardfs_getattr, |
1080 | }; |
1081 |