blob: ba1c7d971ea14b04fa28aeb3cdebb464c0d37f57 [file] [log] [blame]
Daniel Campello593d6622015-07-20 16:23:50 -07001/*
2 * fs/sdcardfs/sdcardfs.h
3 *
4 * The sdcardfs v2.0
5 * This file system replaces the sdcard daemon on Android
6 * On version 2.0, some of the daemon functions have been ported
7 * to support the multi-user concepts of Android 4.4
8 *
9 * Copyright (c) 2013 Samsung Electronics Co. Ltd
10 * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
11 * Sunghwan Yun, Sungjong Seo
12 *
13 * This program has been developed as a stackable file system based on
14 * the WrapFS which written by
15 *
16 * Copyright (c) 1998-2011 Erez Zadok
17 * Copyright (c) 2009 Shrikar Archak
18 * Copyright (c) 2003-2011 Stony Brook University
19 * Copyright (c) 2003-2011 The Research Foundation of SUNY
20 *
21 * This file is dual licensed. It may be redistributed and/or modified
22 * under the terms of the Apache 2.0 License OR version 2 of the GNU
23 * General Public License.
24 */
25
26#ifndef _SDCARDFS_H_
27#define _SDCARDFS_H_
28
29#include <linux/dcache.h>
30#include <linux/file.h>
31#include <linux/fs.h>
32#include <linux/mm.h>
33#include <linux/mount.h>
34#include <linux/namei.h>
35#include <linux/seq_file.h>
36#include <linux/statfs.h>
37#include <linux/fs_stack.h>
38#include <linux/magic.h>
39#include <linux/uaccess.h>
40#include <linux/slab.h>
41#include <linux/sched.h>
42#include <linux/types.h>
43#include <linux/security.h>
44#include <linux/string.h>
Daniel Rosenberg95e17212016-02-03 21:08:21 -080045#include <linux/list.h>
Daniel Campello593d6622015-07-20 16:23:50 -070046#include "multiuser.h"
47
48/* the file system name */
49#define SDCARDFS_NAME "sdcardfs"
50
51/* sdcardfs root inode number */
52#define SDCARDFS_ROOT_INO 1
53
54/* useful for tracking code reachability */
55#define UDBG printk(KERN_DEFAULT "DBG:%s:%s:%d\n", __FILE__, __func__, __LINE__)
56
57#define SDCARDFS_DIRENT_SIZE 256
58
59/* temporary static uid settings for development */
60#define AID_ROOT 0 /* uid for accessing /mnt/sdcard & extSdcard */
61#define AID_MEDIA_RW 1023 /* internal media storage write access */
62
63#define AID_SDCARD_RW 1015 /* external storage write access */
64#define AID_SDCARD_R 1028 /* external storage read access */
65#define AID_SDCARD_PICS 1033 /* external storage photos access */
66#define AID_SDCARD_AV 1034 /* external storage audio/video access */
67#define AID_SDCARD_ALL 1035 /* access all users external storage */
68
69#define AID_PACKAGE_INFO 1027
70
71#define fix_derived_permission(x) \
72 do { \
73 (x)->i_uid = SDCARDFS_I(x)->d_uid; \
Daniel Rosenberg95e17212016-02-03 21:08:21 -080074 (x)->i_gid = get_gid(SDCARDFS_I(x)); \
75 (x)->i_mode = ((x)->i_mode & S_IFMT) | get_mode(SDCARDFS_I(x));\
Daniel Campello593d6622015-07-20 16:23:50 -070076 } while (0)
77
78/* OVERRIDE_CRED() and REVERT_CRED()
79 * OVERRID_CRED()
80 * backup original task->cred
81 * and modifies task->cred->fsuid/fsgid to specified value.
82 * REVERT_CRED()
83 * restore original task->cred->fsuid/fsgid.
84 * These two macro should be used in pair, and OVERRIDE_CRED() should be
85 * placed at the beginning of a function, right after variable declaration.
86 */
87#define OVERRIDE_CRED(sdcardfs_sbi, saved_cred) \
88 saved_cred = override_fsids(sdcardfs_sbi); \
89 if (!saved_cred) { return -ENOMEM; }
90
91#define OVERRIDE_CRED_PTR(sdcardfs_sbi, saved_cred) \
92 saved_cred = override_fsids(sdcardfs_sbi); \
93 if (!saved_cred) { return ERR_PTR(-ENOMEM); }
94
95#define REVERT_CRED(saved_cred) revert_fsids(saved_cred)
96
97#define DEBUG_CRED() \
98 printk("KAKJAGI: %s:%d fsuid %d fsgid %d\n", \
99 __FUNCTION__, __LINE__, \
100 (int)current->cred->fsuid, \
101 (int)current->cred->fsgid);
102
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800103/* Android 5.0 support */
Daniel Campello593d6622015-07-20 16:23:50 -0700104
105/* Permission mode for a specific node. Controls how file permissions
106 * are derived for children nodes. */
107typedef enum {
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800108 /* Nothing special; this node should just inherit from its parent. */
109 PERM_INHERIT,
110 /* This node is one level above a normal root; used for legacy layouts
111 * which use the first level to represent user_id. */
112 PERM_PRE_ROOT,
113 /* This node is "/" */
114 PERM_ROOT,
115 /* This node is "/Android" */
116 PERM_ANDROID,
117 /* This node is "/Android/data" */
118 PERM_ANDROID_DATA,
119 /* This node is "/Android/obb" */
120 PERM_ANDROID_OBB,
121 /* This node is "/Android/media" */
122 PERM_ANDROID_MEDIA,
Daniel Campello593d6622015-07-20 16:23:50 -0700123} perm_t;
124
Daniel Campello593d6622015-07-20 16:23:50 -0700125typedef enum {
126 LOWER_FS_EXT4,
127 LOWER_FS_FAT,
128} lower_fs_t;
129
130struct sdcardfs_sb_info;
131struct sdcardfs_mount_options;
132
133/* Do not directly use this function. Use OVERRIDE_CRED() instead. */
134const struct cred * override_fsids(struct sdcardfs_sb_info* sbi);
135/* Do not directly use this function, use REVERT_CRED() instead. */
136void revert_fsids(const struct cred * old_cred);
137
138/* operations vectors defined in specific files */
139extern const struct file_operations sdcardfs_main_fops;
140extern const struct file_operations sdcardfs_dir_fops;
141extern const struct inode_operations sdcardfs_main_iops;
142extern const struct inode_operations sdcardfs_dir_iops;
143extern const struct inode_operations sdcardfs_symlink_iops;
144extern const struct super_operations sdcardfs_sops;
145extern const struct dentry_operations sdcardfs_ci_dops;
146extern const struct address_space_operations sdcardfs_aops, sdcardfs_dummy_aops;
147extern const struct vm_operations_struct sdcardfs_vm_ops;
148
149extern int sdcardfs_init_inode_cache(void);
150extern void sdcardfs_destroy_inode_cache(void);
151extern int sdcardfs_init_dentry_cache(void);
152extern void sdcardfs_destroy_dentry_cache(void);
153extern int new_dentry_private_data(struct dentry *dentry);
154extern void free_dentry_private_data(struct dentry *dentry);
155extern struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry,
156 struct nameidata *nd);
fluxi41b26d82016-07-29 18:52:13 +0200157extern struct inode *sdcardfs_iget(struct super_block *sb,
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800158 struct inode *lower_inode, userid_t id);
Daniel Campello593d6622015-07-20 16:23:50 -0700159extern int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800160 struct path *lower_path, userid_t id);
Daniel Campello593d6622015-07-20 16:23:50 -0700161
162/* file private data */
163struct sdcardfs_file_info {
164 struct file *lower_file;
165 const struct vm_operations_struct *lower_vm_ops;
166};
167
168/* sdcardfs inode data in memory */
169struct sdcardfs_inode_info {
170 struct inode *lower_inode;
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800171 /* state derived based on current position in hierachy */
Daniel Campello593d6622015-07-20 16:23:50 -0700172 perm_t perm;
173 userid_t userid;
174 uid_t d_uid;
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800175 bool under_android;
Daniel Campello593d6622015-07-20 16:23:50 -0700176
177 struct inode vfs_inode;
178};
179
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800180
Daniel Campello593d6622015-07-20 16:23:50 -0700181/* sdcardfs dentry data in memory */
182struct sdcardfs_dentry_info {
183 spinlock_t lock; /* protects lower_path */
184 struct path lower_path;
185 struct path orig_path;
186};
187
188struct sdcardfs_mount_options {
189 uid_t fs_low_uid;
190 gid_t fs_low_gid;
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800191 userid_t fs_user_id;
192 gid_t gid;
Daniel Campello593d6622015-07-20 16:23:50 -0700193 lower_fs_t lower_fs;
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800194 mode_t mask;
195 bool multiuser;
Daniel Campello593d6622015-07-20 16:23:50 -0700196 unsigned int reserved_mb;
197};
198
199/* sdcardfs super-block data in memory */
200struct sdcardfs_sb_info {
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800201 struct super_block *sb;
Daniel Campello593d6622015-07-20 16:23:50 -0700202 struct super_block *lower_sb;
203 /* derived perm policy : some of options have been added
204 * to sdcardfs_mount_options (Android 4.4 support) */
205 struct sdcardfs_mount_options options;
206 spinlock_t lock; /* protects obbpath */
207 char *obbpath_s;
208 struct path obbpath;
209 void *pkgl_id;
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800210 struct list_head list;
Daniel Campello593d6622015-07-20 16:23:50 -0700211};
212
213/*
214 * inode to private data
215 *
216 * Since we use containers and the struct inode is _inside_ the
217 * sdcardfs_inode_info structure, SDCARDFS_I will always (given a non-NULL
218 * inode pointer), return a valid non-NULL pointer.
219 */
220static inline struct sdcardfs_inode_info *SDCARDFS_I(const struct inode *inode)
221{
222 return container_of(inode, struct sdcardfs_inode_info, vfs_inode);
223}
224
225/* dentry to private data */
226#define SDCARDFS_D(dent) ((struct sdcardfs_dentry_info *)(dent)->d_fsdata)
227
228/* superblock to private data */
229#define SDCARDFS_SB(super) ((struct sdcardfs_sb_info *)(super)->s_fs_info)
230
231/* file to private Data */
232#define SDCARDFS_F(file) ((struct sdcardfs_file_info *)((file)->private_data))
233
234/* file to lower file */
235static inline struct file *sdcardfs_lower_file(const struct file *f)
236{
237 return SDCARDFS_F(f)->lower_file;
238}
239
240static inline void sdcardfs_set_lower_file(struct file *f, struct file *val)
241{
242 SDCARDFS_F(f)->lower_file = val;
243}
244
245/* inode to lower inode. */
246static inline struct inode *sdcardfs_lower_inode(const struct inode *i)
247{
248 return SDCARDFS_I(i)->lower_inode;
249}
250
251static inline void sdcardfs_set_lower_inode(struct inode *i, struct inode *val)
252{
253 SDCARDFS_I(i)->lower_inode = val;
254}
255
256/* superblock to lower superblock */
257static inline struct super_block *sdcardfs_lower_super(
258 const struct super_block *sb)
259{
260 return SDCARDFS_SB(sb)->lower_sb;
261}
262
263static inline void sdcardfs_set_lower_super(struct super_block *sb,
264 struct super_block *val)
265{
266 SDCARDFS_SB(sb)->lower_sb = val;
267}
268
269/* path based (dentry/mnt) macros */
270static inline void pathcpy(struct path *dst, const struct path *src)
271{
272 dst->dentry = src->dentry;
273 dst->mnt = src->mnt;
274}
275
276/* sdcardfs_get_pname functions calls path_get()
277 * therefore, the caller must call "proper" path_put functions
278 */
279#define SDCARDFS_DENT_FUNC(pname) \
280static inline void sdcardfs_get_##pname(const struct dentry *dent, \
281 struct path *pname) \
282{ \
283 spin_lock(&SDCARDFS_D(dent)->lock); \
284 pathcpy(pname, &SDCARDFS_D(dent)->pname); \
285 path_get(pname); \
286 spin_unlock(&SDCARDFS_D(dent)->lock); \
287 return; \
288} \
289static inline void sdcardfs_put_##pname(const struct dentry *dent, \
290 struct path *pname) \
291{ \
292 path_put(pname); \
293 return; \
294} \
295static inline void sdcardfs_set_##pname(const struct dentry *dent, \
296 struct path *pname) \
297{ \
298 spin_lock(&SDCARDFS_D(dent)->lock); \
299 pathcpy(&SDCARDFS_D(dent)->pname, pname); \
300 spin_unlock(&SDCARDFS_D(dent)->lock); \
301 return; \
302} \
303static inline void sdcardfs_reset_##pname(const struct dentry *dent) \
304{ \
305 spin_lock(&SDCARDFS_D(dent)->lock); \
306 SDCARDFS_D(dent)->pname.dentry = NULL; \
307 SDCARDFS_D(dent)->pname.mnt = NULL; \
308 spin_unlock(&SDCARDFS_D(dent)->lock); \
309 return; \
310} \
311static inline void sdcardfs_put_reset_##pname(const struct dentry *dent) \
312{ \
313 struct path pname; \
314 spin_lock(&SDCARDFS_D(dent)->lock); \
315 if(SDCARDFS_D(dent)->pname.dentry) { \
316 pathcpy(&pname, &SDCARDFS_D(dent)->pname); \
317 SDCARDFS_D(dent)->pname.dentry = NULL; \
318 SDCARDFS_D(dent)->pname.mnt = NULL; \
319 spin_unlock(&SDCARDFS_D(dent)->lock); \
320 path_put(&pname); \
321 } else \
322 spin_unlock(&SDCARDFS_D(dent)->lock); \
323 return; \
324}
325
326SDCARDFS_DENT_FUNC(lower_path)
327SDCARDFS_DENT_FUNC(orig_path)
328
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800329static inline int get_gid(struct sdcardfs_inode_info *info) {
330 struct sdcardfs_sb_info *sb_info = SDCARDFS_SB(info->vfs_inode.i_sb);
331 if (sb_info->options.gid == AID_SDCARD_RW) {
332 /* As an optimization, certain trusted system components only run
333 * as owner but operate across all users. Since we're now handing
334 * out the sdcard_rw GID only to trusted apps, we're okay relaxing
335 * the user boundary enforcement for the default view. The UIDs
336 * assigned to app directories are still multiuser aware. */
337 return AID_SDCARD_RW;
338 } else {
339 return multiuser_get_uid(info->userid, sb_info->options.gid);
340 }
341}
342static inline int get_mode(struct sdcardfs_inode_info *info) {
343 int owner_mode;
344 int filtered_mode;
345 struct sdcardfs_sb_info *sb_info = SDCARDFS_SB(info->vfs_inode.i_sb);
346 int visible_mode = 0775 & ~sb_info->options.mask;
347
348 if (info->perm == PERM_PRE_ROOT) {
349 /* Top of multi-user view should always be visible to ensure
350 * secondary users can traverse inside. */
351 visible_mode = 0711;
352 } else if (info->under_android) {
353 /* Block "other" access to Android directories, since only apps
354 * belonging to a specific user should be in there; we still
355 * leave +x open for the default view. */
356 if (sb_info->options.gid == AID_SDCARD_RW) {
357 visible_mode = visible_mode & ~0006;
358 } else {
359 visible_mode = visible_mode & ~0007;
360 }
361 }
362 owner_mode = info->lower_inode->i_mode & 0700;
363 filtered_mode = visible_mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
364 return filtered_mode;
365}
366
Daniel Campello593d6622015-07-20 16:23:50 -0700367static inline int has_graft_path(const struct dentry *dent)
368{
369 int ret = 0;
370
371 spin_lock(&SDCARDFS_D(dent)->lock);
372 if (SDCARDFS_D(dent)->orig_path.dentry != NULL)
373 ret = 1;
374 spin_unlock(&SDCARDFS_D(dent)->lock);
375
376 return ret;
377}
378
379static inline void sdcardfs_get_real_lower(const struct dentry *dent,
380 struct path *real_lower)
381{
382 /* in case of a local obb dentry
383 * the orig_path should be returned
384 */
385 if(has_graft_path(dent))
386 sdcardfs_get_orig_path(dent, real_lower);
387 else
388 sdcardfs_get_lower_path(dent, real_lower);
389}
390
391static inline void sdcardfs_put_real_lower(const struct dentry *dent,
392 struct path *real_lower)
393{
394 if(has_graft_path(dent))
395 sdcardfs_put_orig_path(dent, real_lower);
396 else
397 sdcardfs_put_lower_path(dent, real_lower);
398}
399
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800400extern struct mutex sdcardfs_super_list_lock;
401extern struct list_head sdcardfs_super_list;
402
Daniel Campello593d6622015-07-20 16:23:50 -0700403/* for packagelist.c */
Daniel Campello593d6622015-07-20 16:23:50 -0700404extern appid_t get_appid(void *pkgl_id, const char *app_name);
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800405extern int check_caller_access_to_name(struct inode *parent_node, const char* name);
Daniel Campello593d6622015-07-20 16:23:50 -0700406extern int open_flags_to_access_mode(int open_flags);
Daniel Campello593d6622015-07-20 16:23:50 -0700407extern int packagelist_init(void);
408extern void packagelist_exit(void);
409
410/* for derived_perm.c */
411extern void setup_derived_state(struct inode *inode, perm_t perm,
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800412 userid_t userid, uid_t uid, bool under_android);
Daniel Campello593d6622015-07-20 16:23:50 -0700413extern void get_derived_permission(struct dentry *parent, struct dentry *dentry);
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800414extern void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, struct dentry *newdentry);
415extern void get_derive_permissions_recursive(struct dentry *parent);
416
417extern void update_derived_permission_lock(struct dentry *dentry);
Daniel Campello593d6622015-07-20 16:23:50 -0700418extern int need_graft_path(struct dentry *dentry);
419extern int is_base_obbpath(struct dentry *dentry);
420extern int is_obbpath_invalid(struct dentry *dentry);
421extern int setup_obb_dentry(struct dentry *dentry, struct path *lower_path);
422
423/* locking helpers */
424static inline struct dentry *lock_parent(struct dentry *dentry)
425{
426 struct dentry *dir = dget_parent(dentry);
427 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
428 return dir;
429}
430
431static inline void unlock_dir(struct dentry *dir)
432{
433 mutex_unlock(&dir->d_inode->i_mutex);
434 dput(dir);
435}
436
437static inline int prepare_dir(const char *path_s, uid_t uid, gid_t gid, mode_t mode)
438{
439 int err;
440 struct dentry *dent;
441 struct iattr attrs;
fluxi41b26d82016-07-29 18:52:13 +0200442 struct path parent;
Daniel Campello593d6622015-07-20 16:23:50 -0700443
fluxi41b26d82016-07-29 18:52:13 +0200444 dent = kern_path_locked(path_s, &parent);
Daniel Campello593d6622015-07-20 16:23:50 -0700445 if (IS_ERR(dent)) {
446 err = PTR_ERR(dent);
447 if (err == -EEXIST)
448 err = 0;
449 goto out_unlock;
450 }
451
fluxi41b26d82016-07-29 18:52:13 +0200452 err = vfs_mkdir(parent.dentry->d_inode, dent, mode);
Daniel Campello593d6622015-07-20 16:23:50 -0700453 if (err) {
454 if (err == -EEXIST)
455 err = 0;
456 goto out_dput;
457 }
458
459 attrs.ia_uid = uid;
460 attrs.ia_gid = gid;
461 attrs.ia_valid = ATTR_UID | ATTR_GID;
462 mutex_lock(&dent->d_inode->i_mutex);
463 notify_change(dent, &attrs);
464 mutex_unlock(&dent->d_inode->i_mutex);
465
466out_dput:
467 dput(dent);
468
469out_unlock:
470 /* parent dentry locked by lookup_create */
fluxi41b26d82016-07-29 18:52:13 +0200471 mutex_unlock(&parent.dentry->d_inode->i_mutex);
472 path_put(&parent);
Daniel Campello593d6622015-07-20 16:23:50 -0700473
Daniel Campello593d6622015-07-20 16:23:50 -0700474 return err;
475}
476
477/*
478 * Return 1, if a disk has enough free space, otherwise 0.
479 * We assume that any files can not be overwritten.
480 */
481static inline int check_min_free_space(struct dentry *dentry, size_t size, int dir)
482{
483 int err;
484 struct path lower_path;
485 struct kstatfs statfs;
486 u64 avail;
487 struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
488
489 if (sbi->options.reserved_mb) {
490 /* Get fs stat of lower filesystem. */
491 sdcardfs_get_lower_path(dentry, &lower_path);
492 err = vfs_statfs(&lower_path, &statfs);
493 sdcardfs_put_lower_path(dentry, &lower_path);
494
495 if (unlikely(err))
496 return 0;
497
498 /* Invalid statfs informations. */
499 if (unlikely(statfs.f_bsize == 0))
500 return 0;
501
502 /* if you are checking directory, set size to f_bsize. */
503 if (unlikely(dir))
504 size = statfs.f_bsize;
505
506 /* available size */
507 avail = statfs.f_bavail * statfs.f_bsize;
508
509 /* not enough space */
510 if ((u64)size > avail)
511 return 0;
512
513 /* enough space */
514 if ((avail - size) > (sbi->options.reserved_mb * 1024 * 1024))
515 return 1;
516
517 return 0;
518 } else
519 return 1;
520}
521
Daniel Rosenberg95e17212016-02-03 21:08:21 -0800522/* Copies attrs and maintains sdcardfs managed attrs */
523static inline void sdcardfs_copy_and_fix_attrs(struct inode *dest, const struct inode *src)
524{
525 dest->i_mode = (src->i_mode & S_IFMT) | get_mode(SDCARDFS_I(dest));
526 dest->i_uid = SDCARDFS_I(dest)->d_uid;
527 dest->i_gid = get_gid(SDCARDFS_I(dest));
528 dest->i_rdev = src->i_rdev;
529 dest->i_atime = src->i_atime;
530 dest->i_mtime = src->i_mtime;
531 dest->i_ctime = src->i_ctime;
532 dest->i_blkbits = src->i_blkbits;
533 dest->i_flags = src->i_flags;
534 set_nlink(dest, src->i_nlink);
535}
Daniel Campello593d6622015-07-20 16:23:50 -0700536#endif /* not _SDCARDFS_H_ */