blob: 78a669c8a4d6245c230295cc545243f2a44f190d [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
Daniel Rosenberga56a1052017-05-15 14:03:15 -070029 ci->data->perm = PERM_INHERIT;
30 ci->data->userid = pi->data->userid;
31 ci->data->d_uid = pi->data->d_uid;
32 ci->data->under_android = pi->data->under_android;
33 ci->data->under_cache = pi->data->under_cache;
34 ci->data->under_obb = pi->data->under_obb;
Daniel Campello35c9e242015-07-20 16:23:50 -070035}
36
37/* helper function for derived state */
Daniel Rosenberg5080d242016-05-18 16:57:10 -070038void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid,
Daniel Rosenberg47af77b2018-02-01 16:52:22 -080039 uid_t uid)
Daniel Campello35c9e242015-07-20 16:23:50 -070040{
41 struct sdcardfs_inode_info *info = SDCARDFS_I(inode);
42
Daniel Rosenberga56a1052017-05-15 14:03:15 -070043 info->data->perm = perm;
44 info->data->userid = userid;
45 info->data->d_uid = uid;
Daniel Rosenberg47af77b2018-02-01 16:52:22 -080046 info->data->under_android = false;
Daniel Rosenberga56a1052017-05-15 14:03:15 -070047 info->data->under_cache = false;
48 info->data->under_obb = false;
Daniel Campello35c9e242015-07-20 16:23:50 -070049}
50
Daniel Rosenberg5e024f62017-03-16 17:42:58 -070051/* While renaming, there is a point where we want the path from dentry,
52 * but the name from newdentry
53 */
54void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
55 const struct qstr *name)
Daniel Campello35c9e242015-07-20 16:23:50 -070056{
Daniel Rosenberg63d20762016-12-01 14:36:29 -080057 struct sdcardfs_inode_info *info = SDCARDFS_I(d_inode(dentry));
Daniel Rosenberg47af77b2018-02-01 16:52:22 -080058 struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent));
59 struct sdcardfs_inode_data *parent_data = parent_info->data;
Daniel Campello35c9e242015-07-20 16:23:50 -070060 appid_t appid;
Daniel Rosenberg3c42d402017-03-16 19:32:59 -070061 unsigned long user_num;
62 int err;
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -080063 struct qstr q_Android = QSTR_LITERAL("Android");
64 struct qstr q_data = QSTR_LITERAL("data");
Daniel Rosenbergbe398722018-10-25 16:22:50 -070065 struct qstr q_sandbox = QSTR_LITERAL("sandbox");
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -080066 struct qstr q_obb = QSTR_LITERAL("obb");
67 struct qstr q_media = QSTR_LITERAL("media");
68 struct qstr q_cache = QSTR_LITERAL("cache");
Daniel Campello35c9e242015-07-20 16:23:50 -070069
70 /* By default, each inode inherits from its parent.
71 * the properties are maintained on its private fields
72 * because the inode attributes will be modified with that of
73 * its lower inode.
Daniel Rosenbergad905252017-01-25 13:48:45 -080074 * These values are used by our custom permission call instead
75 * of using the inode permissions.
Daniel Campello35c9e242015-07-20 16:23:50 -070076 */
77
Daniel Rosenberg63d20762016-12-01 14:36:29 -080078 inherit_derived_state(d_inode(parent), d_inode(dentry));
Daniel Campello35c9e242015-07-20 16:23:50 -070079
Daniel Rosenbergad905252017-01-25 13:48:45 -080080 /* Files don't get special labels */
Daniel Rosenberg47af77b2018-02-01 16:52:22 -080081 if (!S_ISDIR(d_inode(dentry)->i_mode)) {
82 set_top(info, parent_info);
Daniel Rosenbergad905252017-01-25 13:48:45 -080083 return;
Daniel Rosenberg47af77b2018-02-01 16:52:22 -080084 }
Daniel Campello35c9e242015-07-20 16:23:50 -070085 /* Derive custom permissions based on parent and current node */
Daniel Rosenberga56a1052017-05-15 14:03:15 -070086 switch (parent_data->perm) {
Daniel Rosenbergad905252017-01-25 13:48:45 -080087 case PERM_INHERIT:
88 case PERM_ANDROID_PACKAGE_CACHE:
Daniel Rosenberg47af77b2018-02-01 16:52:22 -080089 set_top(info, parent_info);
Daniel Rosenbergad905252017-01-25 13:48:45 -080090 break;
91 case PERM_PRE_ROOT:
92 /* Legacy internal layout places users at top level */
Daniel Rosenberga56a1052017-05-15 14:03:15 -070093 info->data->perm = PERM_ROOT;
Daniel Rosenberg3c42d402017-03-16 19:32:59 -070094 err = kstrtoul(name->name, 10, &user_num);
95 if (err)
Daniel Rosenberga56a1052017-05-15 14:03:15 -070096 info->data->userid = 0;
Daniel Rosenberg3c42d402017-03-16 19:32:59 -070097 else
Daniel Rosenberga56a1052017-05-15 14:03:15 -070098 info->data->userid = user_num;
Daniel Rosenbergad905252017-01-25 13:48:45 -080099 break;
100 case PERM_ROOT:
101 /* Assume masked off by default. */
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800102 if (qstr_case_eq(name, &q_Android)) {
Daniel Rosenbergad905252017-01-25 13:48:45 -0800103 /* App-specific directories inside; let anyone traverse */
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700104 info->data->perm = PERM_ANDROID;
105 info->data->under_android = true;
Daniel Rosenberg47af77b2018-02-01 16:52:22 -0800106 } else {
107 set_top(info, parent_info);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800108 }
109 break;
110 case PERM_ANDROID:
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800111 if (qstr_case_eq(name, &q_data)) {
Daniel Rosenbergad905252017-01-25 13:48:45 -0800112 /* App-specific directories inside; let anyone traverse */
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700113 info->data->perm = PERM_ANDROID_DATA;
Daniel Rosenbergbe398722018-10-25 16:22:50 -0700114 } else if (qstr_case_eq(name, &q_sandbox)) {
115 /* App-specific directories inside; let anyone traverse */
116 info->data->perm = PERM_ANDROID_DATA;
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800117 } else if (qstr_case_eq(name, &q_obb)) {
Daniel Rosenbergad905252017-01-25 13:48:45 -0800118 /* App-specific directories inside; let anyone traverse */
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700119 info->data->perm = PERM_ANDROID_OBB;
120 info->data->under_obb = true;
Daniel Rosenbergad905252017-01-25 13:48:45 -0800121 /* Single OBB directory is always shared */
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800122 } else if (qstr_case_eq(name, &q_media)) {
Daniel Rosenbergad905252017-01-25 13:48:45 -0800123 /* App-specific directories inside; let anyone traverse */
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700124 info->data->perm = PERM_ANDROID_MEDIA;
Daniel Rosenberg47af77b2018-02-01 16:52:22 -0800125 } else {
126 set_top(info, parent_info);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800127 }
128 break;
129 case PERM_ANDROID_OBB:
130 case PERM_ANDROID_DATA:
131 case PERM_ANDROID_MEDIA:
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700132 info->data->perm = PERM_ANDROID_PACKAGE;
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800133 appid = get_appid(name->name);
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700134 if (appid != 0 && !is_excluded(name->name, parent_data->userid))
135 info->data->d_uid =
136 multiuser_get_uid(parent_data->userid, appid);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800137 break;
138 case PERM_ANDROID_PACKAGE:
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800139 if (qstr_case_eq(name, &q_cache)) {
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700140 info->data->perm = PERM_ANDROID_PACKAGE_CACHE;
141 info->data->under_cache = true;
Daniel Rosenbergad905252017-01-25 13:48:45 -0800142 }
Daniel Rosenberg47af77b2018-02-01 16:52:22 -0800143 set_top(info, parent_info);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800144 break;
Daniel Campello35c9e242015-07-20 16:23:50 -0700145 }
146}
147
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800148void get_derived_permission(struct dentry *parent, struct dentry *dentry)
149{
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800150 get_derived_permission_new(parent, dentry, &dentry->d_name);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800151}
152
153static appid_t get_type(const char *name)
154{
155 const char *ext = strrchr(name, '.');
156 appid_t id;
157
158 if (ext && ext[0]) {
159 ext = &ext[1];
160 id = get_ext_gid(ext);
161 return id?:AID_MEDIA_RW;
162 }
163 return AID_MEDIA_RW;
164}
165
166void fixup_lower_ownership(struct dentry *dentry, const char *name)
167{
168 struct path path;
169 struct inode *inode;
170 struct inode *delegated_inode = NULL;
171 int error;
172 struct sdcardfs_inode_info *info;
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700173 struct sdcardfs_inode_data *info_d;
174 struct sdcardfs_inode_data *info_top;
Daniel Rosenbergad905252017-01-25 13:48:45 -0800175 perm_t perm;
176 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
177 uid_t uid = sbi->options.fs_low_uid;
178 gid_t gid = sbi->options.fs_low_gid;
179 struct iattr newattrs;
180
Daniel Rosenberg7d10e432017-07-19 17:25:07 -0700181 if (!sbi->options.gid_derivation)
182 return;
183
Daniel Rosenbergad905252017-01-25 13:48:45 -0800184 info = SDCARDFS_I(d_inode(dentry));
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700185 info_d = info->data;
186 perm = info_d->perm;
187 if (info_d->under_obb) {
Daniel Rosenbergad905252017-01-25 13:48:45 -0800188 perm = PERM_ANDROID_OBB;
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700189 } else if (info_d->under_cache) {
Daniel Rosenbergad905252017-01-25 13:48:45 -0800190 perm = PERM_ANDROID_PACKAGE_CACHE;
191 } else if (perm == PERM_INHERIT) {
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700192 info_top = top_data_get(info);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800193 perm = info_top->perm;
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700194 data_put(info_top);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800195 }
196
197 switch (perm) {
198 case PERM_ROOT:
199 case PERM_ANDROID:
200 case PERM_ANDROID_DATA:
201 case PERM_ANDROID_MEDIA:
202 case PERM_ANDROID_PACKAGE:
203 case PERM_ANDROID_PACKAGE_CACHE:
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700204 uid = multiuser_get_uid(info_d->userid, uid);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800205 break;
206 case PERM_ANDROID_OBB:
207 uid = AID_MEDIA_OBB;
208 break;
209 case PERM_PRE_ROOT:
210 default:
211 break;
212 }
213 switch (perm) {
214 case PERM_ROOT:
215 case PERM_ANDROID:
216 case PERM_ANDROID_DATA:
217 case PERM_ANDROID_MEDIA:
218 if (S_ISDIR(d_inode(dentry)->i_mode))
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700219 gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800220 else
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700221 gid = multiuser_get_uid(info_d->userid, get_type(name));
Daniel Rosenbergad905252017-01-25 13:48:45 -0800222 break;
223 case PERM_ANDROID_OBB:
224 gid = AID_MEDIA_OBB;
225 break;
226 case PERM_ANDROID_PACKAGE:
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700227 if (uid_is_app(info_d->d_uid))
228 gid = multiuser_get_ext_gid(info_d->d_uid);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800229 else
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700230 gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800231 break;
232 case PERM_ANDROID_PACKAGE_CACHE:
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700233 if (uid_is_app(info_d->d_uid))
234 gid = multiuser_get_ext_cache_gid(info_d->d_uid);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800235 else
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700236 gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800237 break;
238 case PERM_PRE_ROOT:
239 default:
240 break;
241 }
242
243 sdcardfs_get_lower_path(dentry, &path);
244 inode = d_inode(path.dentry);
245 if (d_inode(path.dentry)->i_gid.val != gid || d_inode(path.dentry)->i_uid.val != uid) {
246retry_deleg:
247 newattrs.ia_valid = ATTR_GID | ATTR_UID | ATTR_FORCE;
248 newattrs.ia_uid = make_kuid(current_user_ns(), uid);
249 newattrs.ia_gid = make_kgid(current_user_ns(), gid);
250 if (!S_ISDIR(inode->i_mode))
251 newattrs.ia_valid |=
252 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
253 inode_lock(inode);
254 error = security_path_chown(&path, newattrs.ia_uid, newattrs.ia_gid);
255 if (!error)
256 error = notify_change2(path.mnt, path.dentry, &newattrs, &delegated_inode);
257 inode_unlock(inode);
258 if (delegated_inode) {
259 error = break_deleg_wait(&delegated_inode);
260 if (!error)
261 goto retry_deleg;
262 }
263 if (error)
Daniel Rosenberg33efe542017-04-18 22:49:38 -0700264 pr_debug("sdcardfs: Failed to touch up lower fs gid/uid for %s\n", name);
Daniel Rosenbergad905252017-01-25 13:48:45 -0800265 }
Daniel Rosenbergf61bc5a2017-02-16 17:55:22 -0800266 sdcardfs_put_lower_path(dentry, &path);
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800267}
268
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700269static int descendant_may_need_fixup(struct sdcardfs_inode_data *data,
270 struct limit_search *limit)
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800271{
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700272 if (data->perm == PERM_ROOT)
273 return (limit->flags & BY_USERID) ?
274 data->userid == limit->userid : 1;
275 if (data->perm == PERM_PRE_ROOT || data->perm == PERM_ANDROID)
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700276 return 1;
277 return 0;
278}
279
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700280static int needs_fixup(perm_t perm)
281{
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700282 if (perm == PERM_ANDROID_DATA || perm == PERM_ANDROID_OBB
283 || perm == PERM_ANDROID_MEDIA)
284 return 1;
285 return 0;
286}
287
Daniel Rosenbergfb4d1912017-03-02 15:11:27 -0800288static void __fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit, int depth)
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800289{
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700290 struct dentry *child;
291 struct sdcardfs_inode_info *info;
Daniel Rosenbergfb4d1912017-03-02 15:11:27 -0800292
293 /*
294 * All paths will terminate their recursion on hitting PERM_ANDROID_OBB,
295 * PERM_ANDROID_MEDIA, or PERM_ANDROID_DATA. This happens at a depth of
296 * at most 3.
297 */
298 WARN(depth > 3, "%s: Max expected depth exceeded!\n", __func__);
299 spin_lock_nested(&dentry->d_lock, depth);
Daniel Rosenberg63d20762016-12-01 14:36:29 -0800300 if (!d_inode(dentry)) {
Daniel Rosenbergfb4d1912017-03-02 15:11:27 -0800301 spin_unlock(&dentry->d_lock);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700302 return;
303 }
304 info = SDCARDFS_I(d_inode(dentry));
305
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700306 if (needs_fixup(info->data->perm)) {
Daniel Rosenberg3adfc032016-12-27 12:36:29 -0800307 list_for_each_entry(child, &dentry->d_subdirs, d_child) {
Daniel Rosenbergfb4d1912017-03-02 15:11:27 -0800308 spin_lock_nested(&child->d_lock, depth + 1);
Daniel Rosenberg721274a2017-03-08 17:20:02 -0800309 if (!(limit->flags & BY_NAME) || qstr_case_eq(&child->d_name, &limit->name)) {
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800310 if (d_inode(child)) {
311 get_derived_permission(dentry, child);
312 fixup_tmp_permissions(d_inode(child));
Daniel Rosenbergfb4d1912017-03-02 15:11:27 -0800313 spin_unlock(&child->d_lock);
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800314 break;
Daniel Rosenberg3adfc032016-12-27 12:36:29 -0800315 }
Daniel Rosenbergd8caaf92017-01-22 15:32:49 -0800316 }
Daniel Rosenbergfb4d1912017-03-02 15:11:27 -0800317 spin_unlock(&child->d_lock);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700318 }
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700319 } else if (descendant_may_need_fixup(info->data, limit)) {
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700320 list_for_each_entry(child, &dentry->d_subdirs, d_child) {
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700321 __fixup_perms_recursive(child, limit, depth + 1);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700322 }
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700323 }
Daniel Rosenbergfb4d1912017-03-02 15:11:27 -0800324 spin_unlock(&dentry->d_lock);
325}
326
327void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit)
328{
329 __fixup_perms_recursive(dentry, limit, 0);
Daniel Rosenberg5080d242016-05-18 16:57:10 -0700330}
331
Daniel Campello35c9e242015-07-20 16:23:50 -0700332/* main function for updating derived permission */
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800333inline void update_derived_permission_lock(struct dentry *dentry)
Daniel Campello35c9e242015-07-20 16:23:50 -0700334{
335 struct dentry *parent;
336
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700337 if (!dentry || !d_inode(dentry)) {
Daniel Rosenberg77ecf212017-03-16 17:46:13 -0700338 pr_err("sdcardfs: %s: invalid dentry\n", __func__);
Daniel Campello35c9e242015-07-20 16:23:50 -0700339 return;
340 }
341 /* FIXME:
342 * 1. need to check whether the dentry is updated or not
343 * 2. remove the root dentry update
344 */
Daniel Rosenbergd64126c2017-03-16 19:33:35 -0700345 if (!IS_ROOT(dentry)) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700346 parent = dget_parent(dentry);
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700347 if (parent) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700348 get_derived_permission(parent, dentry);
349 dput(parent);
350 }
351 }
Daniel Rosenberg90219272016-10-26 20:27:20 -0700352 fixup_tmp_permissions(d_inode(dentry));
Daniel Campello35c9e242015-07-20 16:23:50 -0700353}
354
355int need_graft_path(struct dentry *dentry)
356{
357 int ret = 0;
358 struct dentry *parent = dget_parent(dentry);
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700359 struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent));
Daniel Campello35c9e242015-07-20 16:23:50 -0700360 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800361 struct qstr obb = QSTR_LITERAL("obb");
Daniel Campello35c9e242015-07-20 16:23:50 -0700362
Daniel Rosenberg961ef0a2018-10-25 16:25:15 -0700363 if (!sbi->options.unshared_obb &&
364 parent_info->data->perm == PERM_ANDROID &&
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800365 qstr_case_eq(&dentry->d_name, &obb)) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700366
367 /* /Android/obb is the base obbpath of DERIVED_UNIFIED */
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700368 if (!(sbi->options.multiuser == false
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700369 && parent_info->data->userid == 0)) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700370 ret = 1;
371 }
372 }
373 dput(parent);
374 return ret;
375}
376
377int is_obbpath_invalid(struct dentry *dent)
378{
379 int ret = 0;
380 struct sdcardfs_dentry_info *di = SDCARDFS_D(dent);
381 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dent->d_sb);
382 char *path_buf, *obbpath_s;
Daniel Rosenberge2538da2017-03-10 13:54:30 -0800383 int need_put = 0;
384 struct path lower_path;
Daniel Campello35c9e242015-07-20 16:23:50 -0700385
386 /* check the base obbpath has been changed.
387 * this routine can check an uninitialized obb dentry as well.
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700388 * regarding the uninitialized obb, refer to the sdcardfs_mkdir()
389 */
Daniel Campello35c9e242015-07-20 16:23:50 -0700390 spin_lock(&di->lock);
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700391 if (di->orig_path.dentry) {
392 if (!di->lower_path.dentry) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700393 ret = 1;
394 } else {
395 path_get(&di->lower_path);
Daniel Campello35c9e242015-07-20 16:23:50 -0700396
397 path_buf = kmalloc(PATH_MAX, GFP_ATOMIC);
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700398 if (!path_buf) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700399 ret = 1;
Daniel Rosenberg77ecf212017-03-16 17:46:13 -0700400 pr_err("sdcardfs: fail to allocate path_buf in %s.\n", __func__);
Daniel Campello35c9e242015-07-20 16:23:50 -0700401 } else {
402 obbpath_s = d_path(&di->lower_path, path_buf, PATH_MAX);
403 if (d_unhashed(di->lower_path.dentry) ||
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800404 !str_case_eq(sbi->obbpath_s, obbpath_s)) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700405 ret = 1;
406 }
407 kfree(path_buf);
408 }
409
Daniel Rosenberge2538da2017-03-10 13:54:30 -0800410 pathcpy(&lower_path, &di->lower_path);
411 need_put = 1;
Daniel Campello35c9e242015-07-20 16:23:50 -0700412 }
413 }
414 spin_unlock(&di->lock);
Daniel Rosenberge2538da2017-03-10 13:54:30 -0800415 if (need_put)
416 path_put(&lower_path);
Daniel Campello35c9e242015-07-20 16:23:50 -0700417 return ret;
418}
419
420int is_base_obbpath(struct dentry *dentry)
421{
422 int ret = 0;
423 struct dentry *parent = dget_parent(dentry);
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700424 struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent));
Daniel Campello35c9e242015-07-20 16:23:50 -0700425 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800426 struct qstr q_obb = QSTR_LITERAL("obb");
Daniel Campello35c9e242015-07-20 16:23:50 -0700427
428 spin_lock(&SDCARDFS_D(dentry)->lock);
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800429 if (sbi->options.multiuser) {
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700430 if (parent_info->data->perm == PERM_PRE_ROOT &&
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800431 qstr_case_eq(&dentry->d_name, &q_obb)) {
Daniel Rosenberg497ac902016-02-03 21:08:21 -0800432 ret = 1;
433 }
Daniel Rosenberga56a1052017-05-15 14:03:15 -0700434 } else if (parent_info->data->perm == PERM_ANDROID &&
Daniel Rosenberg5004c5f2017-01-31 20:07:51 -0800435 qstr_case_eq(&dentry->d_name, &q_obb)) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700436 ret = 1;
437 }
Daniel Campello35c9e242015-07-20 16:23:50 -0700438 spin_unlock(&SDCARDFS_D(dentry)->lock);
Daniel Campello35c9e242015-07-20 16:23:50 -0700439 return ret;
440}
441
442/* The lower_path will be stored to the dentry's orig_path
443 * and the base obbpath will be copyed to the lower_path variable.
444 * if an error returned, there's no change in the lower_path
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700445 * returns: -ERRNO if error (0: no error)
446 */
Daniel Campello35c9e242015-07-20 16:23:50 -0700447int 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
Daniel Rosenbergd64126c2017-03-16 19:33:35 -0700455 * is avaiable on this stage.
456 */
Daniel Campello35c9e242015-07-20 16:23:50 -0700457 sdcardfs_set_orig_path(dentry, lower_path);
458
459 err = kern_path(sbi->obbpath_s,
460 LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &obbpath);
461
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700462 if (!err) {
Daniel Campello35c9e242015-07-20 16:23:50 -0700463 /* the obbpath base has been found */
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
Daniel Rosenberg5e024f62017-03-16 17:42:58 -0700470 * a lookup fail.
471 */
Daniel Rosenberg77ecf212017-03-16 17:46:13 -0700472 pr_info("sdcardfs: the sbi->obbpath is not available\n");
Daniel Campello35c9e242015-07-20 16:23:50 -0700473 }
474 return err;
475}
476
477