blob: 16f05172f9bf508967a2380d90e9828b9b143d95 [file] [log] [blame]
Daniel Campello35c9e242015-07-20 16:23:50 -07001/*
2 * fs/sdcardfs/derived_perm.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
23/* copy derived state from parent inode */
24static void inherit_derived_state(struct inode *parent, struct inode *child)
25{
26 struct sdcardfs_inode_info *pi = SDCARDFS_I(parent);
27 struct sdcardfs_inode_info *ci = SDCARDFS_I(child);
28
29 ci->perm = PERM_INHERIT;
30 ci->userid = pi->userid;
31 ci->d_uid = pi->d_uid;
Daniel Rosenberg497ac902016-02-03 21:08:21 -080032 ci->under_android = pi->under_android;
Daniel Rosenbergad905252017-01-25 13:48:45 -080033 ci->under_cache = pi->under_cache;
34 ci->under_obb = pi->under_obb;
Daniel Rosenberg5080d242016-05-18 16:57:10 -070035 set_top(ci, pi->top);
Daniel Campello35c9e242015-07-20 16:23:50 -070036}
37
38/* helper function for derived state */
Daniel Rosenberg5080d242016-05-18 16:57:10 -070039void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid,
40 uid_t uid, bool under_android, struct inode *top)
Daniel Campello35c9e242015-07-20 16:23:50 -070041{
42 struct sdcardfs_inode_info *info = SDCARDFS_I(inode);
43
44 info->perm = perm;
45 info->userid = userid;
46 info->d_uid = uid;
Daniel Rosenberg497ac902016-02-03 21:08:21 -080047 info->under_android = under_android;
Daniel Rosenbergad905252017-01-25 13:48:45 -080048 info->under_cache = false;
49 info->under_obb = false;
Daniel Rosenberg5080d242016-05-18 16:57:10 -070050 set_top(info, top);
Daniel Campello35c9e242015-07-20 16:23:50 -070051}
52
Daniel Rosenberg497ac902016-02-03 21:08:21 -080053/* While renaming, there is a point where we want the path from dentry, but the name from newdentry */
Daniel Rosenbergad905252017-01-25 13:48:45 -080054void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, const char *name)
Daniel Campello35c9e242015-07-20 16:23:50 -070055{
Daniel Rosenberg63d20762016-12-01 14:36:29 -080056 struct sdcardfs_inode_info *info = SDCARDFS_I(d_inode(dentry));
57 struct sdcardfs_inode_info *parent_info= SDCARDFS_I(d_inode(parent));
Daniel Campello35c9e242015-07-20 16:23:50 -070058 appid_t appid;
59
60 /* By default, each inode inherits from its parent.
61 * the properties are maintained on its private fields
62 * because the inode attributes will be modified with that of
63 * its lower inode.
Daniel Rosenbergad905252017-01-25 13:48:45 -080064 * These values are used by our custom permission call instead
65 * of using the inode permissions.
Daniel Campello35c9e242015-07-20 16:23:50 -070066 */
67
Daniel Rosenberg63d20762016-12-01 14:36:29 -080068 inherit_derived_state(d_inode(parent), d_inode(dentry));
Daniel Campello35c9e242015-07-20 16:23:50 -070069
Daniel Rosenbergad905252017-01-25 13:48:45 -080070 /* Files don't get special labels */
71 if (!S_ISDIR(d_inode(dentry)->i_mode))
72 return;
Daniel Campello35c9e242015-07-20 16:23:50 -070073 /* Derive custom permissions based on parent and current node */
74 switch (parent_info->perm) {
Daniel Rosenbergad905252017-01-25 13:48:45 -080075 case PERM_INHERIT:
76 case PERM_ANDROID_PACKAGE_CACHE:
77 /* Already inherited above */
78 break;
79 case PERM_PRE_ROOT:
80 /* Legacy internal layout places users at top level */
81 info->perm = PERM_ROOT;
82 info->userid = simple_strtoul(name, NULL, 10);
83 set_top(info, &info->vfs_inode);
84 break;
85 case PERM_ROOT:
86 /* Assume masked off by default. */
87 if (!strcasecmp(name, "Android")) {
88 /* App-specific directories inside; let anyone traverse */
89 info->perm = PERM_ANDROID;
90 info->under_android = true;
Daniel Rosenberg5080d242016-05-18 16:57:10 -070091 set_top(info, &info->vfs_inode);
Daniel Rosenbergad905252017-01-25 13:48:45 -080092 }
93 break;
94 case PERM_ANDROID:
95 if (!strcasecmp(name, "data")) {
96 /* App-specific directories inside; let anyone traverse */
97 info->perm = PERM_ANDROID_DATA;
Daniel Rosenberg5080d242016-05-18 16:57:10 -070098 set_top(info, &info->vfs_inode);
Daniel Rosenbergad905252017-01-25 13:48:45 -080099 } else if (!strcasecmp(name, "obb")) {
100 /* App-specific directories inside; let anyone traverse */
101 info->perm = PERM_ANDROID_OBB;
102 info->under_obb = true;
103 set_top(info, &info->vfs_inode);
104 /* Single OBB directory is always shared */
105 } else if (!strcasecmp(name, "media")) {
106 /* App-specific directories inside; let anyone traverse */
107 info->perm = PERM_ANDROID_MEDIA;
108 set_top(info, &info->vfs_inode);
109 }
110 break;
111 case PERM_ANDROID_OBB:
112 case PERM_ANDROID_DATA:
113 case PERM_ANDROID_MEDIA:
114 info->perm = PERM_ANDROID_PACKAGE;
115 appid = get_appid(name);
116 if (appid != 0 && !is_excluded(name, parent_info->userid)) {
117 info->d_uid = multiuser_get_uid(parent_info->userid, appid);
118 }
119 set_top(info, &info->vfs_inode);
120 break;
121 case PERM_ANDROID_PACKAGE:
122 if (!strcasecmp(name, "cache")) {
123 info->perm = PERM_ANDROID_PACKAGE_CACHE;
124 info->under_cache = true;
125 }
126 break;
Daniel Campello35c9e242015-07-20 16:23:50 -0700127 }
128}
129
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800130void get_derived_permission(struct dentry *parent, struct dentry *dentry)
131{
Daniel Rosenbergad905252017-01-25 13:48:45 -0800132 get_derived_permission_new(parent, dentry, dentry->d_name.name);
133}
134
135static appid_t get_type(const char *name)
136{
137 const char *ext = strrchr(name, '.');
138 appid_t id;
139
140 if (ext && ext[0]) {
141 ext = &ext[1];
142 id = get_ext_gid(ext);
143 return id?:AID_MEDIA_RW;
144 }
145 return AID_MEDIA_RW;
146}
147
148void fixup_lower_ownership(struct dentry *dentry, const char *name)
149{
150 struct path path;
151 struct inode *inode;
152 struct inode *delegated_inode = NULL;
153 int error;
154 struct sdcardfs_inode_info *info;
155 struct sdcardfs_inode_info *info_top;
156 perm_t perm;
157 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
158 uid_t uid = sbi->options.fs_low_uid;
159 gid_t gid = sbi->options.fs_low_gid;
160 struct iattr newattrs;
161
162 info = SDCARDFS_I(d_inode(dentry));
163 perm = info->perm;
164 if (info->under_obb) {
165 perm = PERM_ANDROID_OBB;
166 } else if (info->under_cache) {
167 perm = PERM_ANDROID_PACKAGE_CACHE;
168 } else if (perm == PERM_INHERIT) {
169 info_top = SDCARDFS_I(grab_top(info));
170 perm = info_top->perm;
171 release_top(info);
172 }
173
174 switch (perm) {
175 case PERM_ROOT:
176 case PERM_ANDROID:
177 case PERM_ANDROID_DATA:
178 case PERM_ANDROID_MEDIA:
179 case PERM_ANDROID_PACKAGE:
180 case PERM_ANDROID_PACKAGE_CACHE:
181 uid = multiuser_get_uid(info->userid, uid);
182 break;
183 case PERM_ANDROID_OBB:
184 uid = AID_MEDIA_OBB;
185 break;
186 case PERM_PRE_ROOT:
187 default:
188 break;
189 }
190 switch (perm) {
191 case PERM_ROOT:
192 case PERM_ANDROID:
193 case PERM_ANDROID_DATA:
194 case PERM_ANDROID_MEDIA:
195 if (S_ISDIR(d_inode(dentry)->i_mode))
196 gid = multiuser_get_uid(info->userid, AID_MEDIA_RW);
197 else
198 gid = multiuser_get_uid(info->userid, get_type(name));
199 break;
200 case PERM_ANDROID_OBB:
201 gid = AID_MEDIA_OBB;
202 break;
203 case PERM_ANDROID_PACKAGE:
204 if (info->d_uid != 0)
205 gid = multiuser_get_ext_gid(info->userid, info->d_uid);
206 else
207 gid = multiuser_get_uid(info->userid, uid);
208 break;
209 case PERM_ANDROID_PACKAGE_CACHE:
210 if (info->d_uid != 0)
211 gid = multiuser_get_cache_gid(info->userid, info->d_uid);
212 else
213 gid = multiuser_get_uid(info->userid, uid);
214 break;
215 case PERM_PRE_ROOT:
216 default:
217 break;
218 }
219
220 sdcardfs_get_lower_path(dentry, &path);
221 inode = d_inode(path.dentry);
222 if (d_inode(path.dentry)->i_gid.val != gid || d_inode(path.dentry)->i_uid.val != uid) {
223retry_deleg:
224 newattrs.ia_valid = ATTR_GID | ATTR_UID | ATTR_FORCE;
225 newattrs.ia_uid = make_kuid(current_user_ns(), uid);
226 newattrs.ia_gid = make_kgid(current_user_ns(), gid);
227 if (!S_ISDIR(inode->i_mode))
228 newattrs.ia_valid |=
229 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
230 inode_lock(inode);
231 error = security_path_chown(&path, newattrs.ia_uid, newattrs.ia_gid);
232 if (!error)
233 error = notify_change2(path.mnt, path.dentry, &newattrs, &delegated_inode);
234 inode_unlock(inode);
235 if (delegated_inode) {
236 error = break_deleg_wait(&delegated_inode);
237 if (!error)
238 goto retry_deleg;
239 }
240 if (error)
241 pr_err("sdcardfs: Failed to touch up lower fs gid/uid.\n");
242 }
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800243}
244
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800245static int descendant_may_need_fixup(struct sdcardfs_inode_info *info, struct limit_search *limit)
246{
247 if (info->perm == PERM_ROOT)
248 return (limit->flags & BY_USERID)?info->userid == limit->userid:1;
249 if (info->perm == PERM_PRE_ROOT || info->perm == PERM_ANDROID)
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700250 return 1;
251 return 0;
252}
253
254static int needs_fixup(perm_t perm) {
255 if (perm == PERM_ANDROID_DATA || perm == PERM_ANDROID_OBB
256 || perm == PERM_ANDROID_MEDIA)
257 return 1;
258 return 0;
259}
260
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800261void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit)
262{
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700263 struct dentry *child;
264 struct sdcardfs_inode_info *info;
265 if (!dget(dentry))
266 return;
Daniel Rosenberg63d20762016-12-01 14:36:29 -0800267 if (!d_inode(dentry)) {
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700268 dput(dentry);
269 return;
270 }
271 info = SDCARDFS_I(d_inode(dentry));
272
273 if (needs_fixup(info->perm)) {
Daniel Rosenberg3adfc032016-12-27 12:36:29 -0800274 spin_lock(&dentry->d_lock);
275 list_for_each_entry(child, &dentry->d_subdirs, d_child) {
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800276 dget(child);
277 if (!(limit->flags & BY_NAME) || !strncasecmp(child->d_name.name, limit->name, limit->length)) {
278 if (d_inode(child)) {
279 get_derived_permission(dentry, child);
280 fixup_tmp_permissions(d_inode(child));
281 dput(child);
282 break;
Daniel Rosenberg3adfc032016-12-27 12:36:29 -0800283 }
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800284 }
285 dput(child);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700286 }
Daniel Rosenberg3adfc032016-12-27 12:36:29 -0800287 spin_unlock(&dentry->d_lock);
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800288 } else if (descendant_may_need_fixup(info, limit)) {
Daniel Rosenberg3adfc032016-12-27 12:36:29 -0800289 spin_lock(&dentry->d_lock);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700290 list_for_each_entry(child, &dentry->d_subdirs, d_child) {
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800291 fixup_perms_recursive(child, limit);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700292 }
Daniel Rosenberg3adfc032016-12-27 12:36:29 -0800293 spin_unlock(&dentry->d_lock);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700294 }
295 dput(dentry);
296}
297
Daniel Rosenbergad905252017-01-25 13:48:45 -0800298void drop_recursive(struct dentry *parent)
299{
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800300 struct dentry *dentry;
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700301 struct sdcardfs_inode_info *info;
302 if (!d_inode(parent))
303 return;
304 info = SDCARDFS_I(d_inode(parent));
Daniel Rosenbergcb1b9452016-08-16 15:19:26 -0700305 spin_lock(&parent->d_lock);
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800306 list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700307 if (d_inode(dentry)) {
308 if (SDCARDFS_I(d_inode(parent))->top != SDCARDFS_I(d_inode(dentry))->top) {
Daniel Rosenbergad905252017-01-25 13:48:45 -0800309 drop_recursive(dentry);
310 d_drop(dentry);
311 }
312 }
313 }
314 spin_unlock(&parent->d_lock);
315}
316
317void fixup_top_recursive(struct dentry *parent)
318{
319 struct dentry *dentry;
320 struct sdcardfs_inode_info *info;
321
322 if (!d_inode(parent))
323 return;
324 info = SDCARDFS_I(d_inode(parent));
325 spin_lock(&parent->d_lock);
326 list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
327 if (d_inode(dentry)) {
328 if (SDCARDFS_I(d_inode(parent))->top != SDCARDFS_I(d_inode(dentry))->top) {
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700329 get_derived_permission(parent, dentry);
Daniel Rosenberg90219272016-10-26 20:27:20 -0700330 fixup_tmp_permissions(d_inode(dentry));
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700331 fixup_top_recursive(dentry);
332 }
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800333 }
334 }
Daniel Rosenbergcb1b9452016-08-16 15:19:26 -0700335 spin_unlock(&parent->d_lock);
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800336}
337
Daniel Campello35c9e242015-07-20 16:23:50 -0700338/* main function for updating derived permission */
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800339inline void update_derived_permission_lock(struct dentry *dentry)
Daniel Campello35c9e242015-07-20 16:23:50 -0700340{
341 struct dentry *parent;
342
Daniel Rosenberg63d20762016-12-01 14:36:29 -0800343 if(!dentry || !d_inode(dentry)) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700344 printk(KERN_ERR "sdcardfs: %s: invalid dentry\n", __func__);
345 return;
346 }
347 /* FIXME:
348 * 1. need to check whether the dentry is updated or not
349 * 2. remove the root dentry update
350 */
351 if(IS_ROOT(dentry)) {
Daniel Rosenberg63d20762016-12-01 14:36:29 -0800352 //setup_default_pre_root_state(d_inode(dentry));
Daniel Campello35c9e242015-07-20 16:23:50 -0700353 } else {
354 parent = dget_parent(dentry);
355 if(parent) {
356 get_derived_permission(parent, dentry);
357 dput(parent);
358 }
359 }
Daniel Rosenberg90219272016-10-26 20:27:20 -0700360 fixup_tmp_permissions(d_inode(dentry));
Daniel Campello35c9e242015-07-20 16:23:50 -0700361}
362
363int need_graft_path(struct dentry *dentry)
364{
365 int ret = 0;
366 struct dentry *parent = dget_parent(dentry);
Daniel Rosenberg63d20762016-12-01 14:36:29 -0800367 struct sdcardfs_inode_info *parent_info= SDCARDFS_I(d_inode(parent));
Daniel Campello35c9e242015-07-20 16:23:50 -0700368 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
369
370 if(parent_info->perm == PERM_ANDROID &&
371 !strcasecmp(dentry->d_name.name, "obb")) {
372
373 /* /Android/obb is the base obbpath of DERIVED_UNIFIED */
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800374 if(!(sbi->options.multiuser == false
Daniel Campello35c9e242015-07-20 16:23:50 -0700375 && parent_info->userid == 0)) {
376 ret = 1;
377 }
378 }
379 dput(parent);
380 return ret;
381}
382
383int is_obbpath_invalid(struct dentry *dent)
384{
385 int ret = 0;
386 struct sdcardfs_dentry_info *di = SDCARDFS_D(dent);
387 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dent->d_sb);
388 char *path_buf, *obbpath_s;
389
390 /* check the base obbpath has been changed.
391 * this routine can check an uninitialized obb dentry as well.
392 * regarding the uninitialized obb, refer to the sdcardfs_mkdir() */
393 spin_lock(&di->lock);
394 if(di->orig_path.dentry) {
395 if(!di->lower_path.dentry) {
396 ret = 1;
397 } else {
398 path_get(&di->lower_path);
399 //lower_parent = lock_parent(lower_path->dentry);
400
401 path_buf = kmalloc(PATH_MAX, GFP_ATOMIC);
402 if(!path_buf) {
403 ret = 1;
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800404 printk(KERN_ERR "sdcardfs: fail to allocate path_buf in %s.\n", __func__);
Daniel Campello35c9e242015-07-20 16:23:50 -0700405 } else {
406 obbpath_s = d_path(&di->lower_path, path_buf, PATH_MAX);
407 if (d_unhashed(di->lower_path.dentry) ||
408 strcasecmp(sbi->obbpath_s, obbpath_s)) {
409 ret = 1;
410 }
411 kfree(path_buf);
412 }
413
414 //unlock_dir(lower_parent);
415 path_put(&di->lower_path);
416 }
417 }
418 spin_unlock(&di->lock);
419 return ret;
420}
421
422int is_base_obbpath(struct dentry *dentry)
423{
424 int ret = 0;
425 struct dentry *parent = dget_parent(dentry);
Daniel Rosenberg63d20762016-12-01 14:36:29 -0800426 struct sdcardfs_inode_info *parent_info= SDCARDFS_I(d_inode(parent));
Daniel Campello35c9e242015-07-20 16:23:50 -0700427 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
428
429 spin_lock(&SDCARDFS_D(dentry)->lock);
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800430 if (sbi->options.multiuser) {
431 if(parent_info->perm == PERM_PRE_ROOT &&
432 !strcasecmp(dentry->d_name.name, "obb")) {
433 ret = 1;
434 }
435 } else if (parent_info->perm == PERM_ANDROID &&
Daniel Campello35c9e242015-07-20 16:23:50 -0700436 !strcasecmp(dentry->d_name.name, "obb")) {
437 ret = 1;
438 }
Daniel Campello35c9e242015-07-20 16:23:50 -0700439 spin_unlock(&SDCARDFS_D(dentry)->lock);
Daniel Campello35c9e242015-07-20 16:23:50 -0700440 return ret;
441}
442
443/* The lower_path will be stored to the dentry's orig_path
444 * and the base obbpath will be copyed to the lower_path variable.
445 * if an error returned, there's no change in the lower_path
446 * returns: -ERRNO if error (0: no error) */
447int setup_obb_dentry(struct dentry *dentry, struct path *lower_path)
448{
449 int err = 0;
450 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
451 struct path obbpath;
452
453 /* A local obb dentry must have its own orig_path to support rmdir
454 * and mkdir of itself. Usually, we expect that the sbi->obbpath
455 * is avaiable on this stage. */
456 sdcardfs_set_orig_path(dentry, lower_path);
457
458 err = kern_path(sbi->obbpath_s,
459 LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &obbpath);
460
461 if(!err) {
462 /* the obbpath base has been found */
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800463 printk(KERN_INFO "sdcardfs: the sbi->obbpath is found\n");
Daniel Campello35c9e242015-07-20 16:23:50 -0700464 pathcpy(lower_path, &obbpath);
465 } else {
466 /* if the sbi->obbpath is not available, we can optionally
467 * setup the lower_path with its orig_path.
468 * but, the current implementation just returns an error
469 * because the sdcard daemon also regards this case as
470 * a lookup fail. */
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800471 printk(KERN_INFO "sdcardfs: the sbi->obbpath is not available\n");
Daniel Campello35c9e242015-07-20 16:23:50 -0700472 }
473 return err;
474}
475
476