1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * fs/hmdfs/comm/authority/authentication.h
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8 #ifndef AUTHENTICATION_H
9 #define AUTHENTICATION_H
10
11 #include <linux/cred.h>
12 #include <linux/fs.h>
13 #include <linux/fs_struct.h>
14 #include <linux/sched/task.h>
15 #include <linux/xattr.h>
16 #include "hmdfs.h"
17
18 struct cache_fs_override {
19 struct fs_struct *saved_fs;
20 struct fs_struct *copied_fs;
21 const struct cred *saved_cred;
22 };
23
24 #ifdef CONFIG_HMDFS_FS_PERMISSION
25
26 #define OID_ROOT 0
27 #define OID_SYSTEM 1000
28 #define OID_USER_DATA_RW 1008
29
30 /* copied from sdcardfs/multiuser.h */
31 #define BASE_USER_RANGE 200000 /* offset for uid ranges for each user */
32
33 #define HMDFS_PERM_XATTR "user.hmdfs.perm"
34
35 #define ROOT_UID KUIDT_INIT(OID_ROOT)
36 #define SYSTEM_UID KUIDT_INIT(OID_SYSTEM)
37 #define USER_DATA_RW_UID KUIDT_INIT(OID_USER_DATA_RW)
38
39 #define ROOT_GID KGIDT_INIT(OID_ROOT)
40 #define SYSTEM_GID KGIDT_INIT(OID_SYSTEM)
41 #define USER_DATA_RW_GID KGIDT_INIT(OID_USER_DATA_RW)
42
43 #define PKG_ROOT_NAME "data"
44 #define SYSTEM_NAME "system"
45
46 /*
47 * | perm fix | permmnt | permdfs | permpkg | perm other
48 * /mnt/mdfs/ accoundID / device view / local / DATA / packageName /...
49 * / system /...
50 * / documents /...
51 * / devid /.......
52 * / merge view /
53 * / sdcard /
54 **/
55 #define HMDFS_PERM_MASK 0x000F
56
57 #define HMDFS_PERM_FIX 0
58 #define HMDFS_PERM_MNT 1
59 #define HMDFS_PERM_DFS 2
60 #define HMDFS_PERM_PKG 3
61 #define HMDFS_PERM_OTHER 4
62
is_perm_fix(__u16 perm)63 static inline bool is_perm_fix(__u16 perm)
64 {
65 return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_FIX;
66 }
67
is_perm_mnt(__u16 perm)68 static inline bool is_perm_mnt(__u16 perm)
69 {
70 return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_MNT;
71 }
72
is_perm_dfs(__u16 perm)73 static inline bool is_perm_dfs(__u16 perm)
74 {
75 return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_DFS;
76 }
77
is_perm_pkg(__u16 perm)78 static inline bool is_perm_pkg(__u16 perm)
79 {
80 return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_PKG;
81 }
82
is_perm_other(__u16 perm)83 static inline bool is_perm_other(__u16 perm)
84 {
85 return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_OTHER;
86 }
87
hmdfs_check_cred(const struct cred * cred)88 static inline void hmdfs_check_cred(const struct cred *cred)
89 {
90 if (cred->fsuid.val != OID_SYSTEM || cred->fsgid.val != OID_SYSTEM)
91 hmdfs_warning("uid is %u, gid is %u", cred->fsuid.val,
92 cred->fsgid.val);
93 }
94
95 /* dir and file type mask for hmdfs */
96 #define HMDFS_DIR_TYPE_MASK 0x00F0
97
98 /* LEVEL 0 perm fix - permmnt , only root dir */
99 #define HMDFS_DIR_ROOT 0x0010
100
101 /* LEVEL 1 perm dfs */
102 #define HMDFS_DIR_PUBLIC 0x0020
103 #define HMDFS_DIR_DATA 0x0030
104 #define HMDFS_DIR_SYSTEM 0x0040
105
106 /* LEVEL 2 HMDFS_PERM_PKG */
107 #define HMDFS_DIR_PKG 0x0050
108
109 /* LEVEL 2~n HMDFS_PERM_OTHER */
110 #define PUBLIC_FILE 0x0060
111 #define PUBLIC_SUB_DIR 0x0070
112 #define SYSTEM_SUB_DIR 0x0080
113 #define SYSTEM_SUB_FILE 0x0090
114
115 #define HMDFS_DIR_PKG_SUB 0x00A0
116 #define HMDFS_FILE_PKG_SUB 0x00B0
117
118 /* access right is derived
119 * PUBLIC_SUB_DIR SYSTEM_SUB_DIR HMDFS_DIR_PKG_SUB
120 * PUBLIC_FILE SYSTEM_SUB_FILE HMDFS_FILE_PKG_SUB
121 */
122 #define HMDFS_DIR_DEFAULT 0x00C0
123 #define HMDFS_FILE_DEFAULT 0x00D0
124 #define HMDFS_TYPE_DEFAULT 0x0000
125
is_data_dir(__u16 perm)126 static inline bool is_data_dir(__u16 perm)
127 {
128 return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_DATA;
129 }
130
is_pkg_dir(__u16 perm)131 static inline bool is_pkg_dir(__u16 perm)
132 {
133 return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_PKG;
134 }
135
is_pkg_sub_dir(__u16 perm)136 static inline bool is_pkg_sub_dir(__u16 perm)
137 {
138 return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_PKG_SUB;
139 }
140
is_pkg_sub_file(__u16 perm)141 static inline bool is_pkg_sub_file(__u16 perm)
142 {
143 return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_FILE_PKG_SUB;
144 }
145
is_default_dir(__u16 perm)146 static inline bool is_default_dir(__u16 perm)
147 {
148 return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_DEFAULT;
149 }
150
is_default_file(__u16 perm)151 static inline bool is_default_file(__u16 perm)
152 {
153 return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_FILE_DEFAULT;
154 }
155
156 #define AUTH_MASK 0x0F00
157 #define AUTH_PKG 0x0100
158 #define AUTH_SYSTEM 0x0200
159
is_pkg_auth(__u16 perm)160 static inline bool is_pkg_auth(__u16 perm)
161 {
162 return (perm & AUTH_MASK) == AUTH_PKG;
163 }
164
is_system_auth(__u16 perm)165 static inline bool is_system_auth(__u16 perm)
166 {
167 return (perm & AUTH_MASK) == AUTH_SYSTEM;
168 }
169
170 #define HMDFS_MOUNT_POINT_MASK 0xF000
171 #define HMDFS_MNT_COMMON 0x0000 // sdcard
172 #define HMDFS_MNT_SDCARD 0x1000 // sdcard
173 #define HMDFS_MNT_ACNTID 0x2000 // accound id
174
175 #define HMDFS_ALL_MASK (HMDFS_MOUNT_POINT_MASK | AUTH_MASK | HMDFS_DIR_TYPE_MASK | HMDFS_PERM_MASK)
176
set_inode_gid(struct inode * inode,kgid_t gid)177 static inline void set_inode_gid(struct inode *inode, kgid_t gid)
178 {
179 inode->i_gid = gid;
180 }
181
get_inode_uid(struct inode * inode)182 static inline kuid_t get_inode_uid(struct inode *inode)
183 {
184 kuid_t uid = inode->i_uid;
185 return uid;
186 }
187
set_inode_uid(struct inode * inode,kuid_t uid)188 static inline void set_inode_uid(struct inode *inode, kuid_t uid)
189 {
190 inode->i_uid = uid;
191 }
192
hmdfs_override_inode_uid(struct inode * inode)193 static inline kuid_t hmdfs_override_inode_uid(struct inode *inode)
194 {
195 kuid_t uid = get_inode_uid(inode);
196
197 set_inode_uid(inode, current_fsuid());
198 return uid;
199 }
200
hmdfs_revert_inode_uid(struct inode * inode,kuid_t uid)201 static inline void hmdfs_revert_inode_uid(struct inode *inode, kuid_t uid)
202 {
203 set_inode_uid(inode, uid);
204 }
205
hmdfs_override_creds(const struct cred * new)206 static inline const struct cred *hmdfs_override_creds(const struct cred *new)
207 {
208 if (!new)
209 return NULL;
210
211 return override_creds(new);
212 }
213
hmdfs_revert_creds(const struct cred * old)214 static inline void hmdfs_revert_creds(const struct cred *old)
215 {
216 if (old)
217 revert_creds(old);
218 }
219
hmdfs_perm_get_next_level(__u16 perm)220 static inline __u16 hmdfs_perm_get_next_level(__u16 perm)
221 {
222 __u16 level = (perm & HMDFS_PERM_MASK) + 1;
223
224 if (level <= HMDFS_PERM_OTHER)
225 return level;
226 else
227 return HMDFS_PERM_OTHER;
228 }
229
230 struct fs_struct *hmdfs_override_fsstruct(struct fs_struct *saved_fs);
231 void hmdfs_revert_fsstruct(struct fs_struct *saved_fs,
232 struct fs_struct *copied_fs);
233 const struct cred *hmdfs_override_fsids(bool is_recv_thread);
234 const struct cred *hmdfs_override_dir_fsids(struct inode *dir,
235 struct dentry *dentry, __u16 *perm);
236 const struct cred *hmdfs_override_file_fsids(struct inode *dir, __u16 *perm);
237 void hmdfs_revert_fsids(const struct cred *old_cred);
238 int hmdfs_persist_perm(struct dentry *dentry, __u16 *perm);
239 __u16 hmdfs_read_perm(struct inode *inode);
240 void hmdfs_root_inode_perm_init(struct inode *root_inode);
241 void check_and_fixup_ownership(struct inode *parent_inode, struct inode *child);
242 int hmdfs_override_dir_id_fs(struct cache_fs_override *or,
243 struct inode *dir,
244 struct dentry *dentry,
245 __u16 *perm);
246 void hmdfs_revert_dir_id_fs(struct cache_fs_override *or);
247 void check_and_fixup_ownership_remote(struct inode *dir,
248 struct dentry *dentry);
249 extern int get_bid(const char *bname);
250 extern int __init hmdfs_init_configfs(void);
251 extern void hmdfs_exit_configfs(void);
252
get_bundle_uid(struct hmdfs_sb_info * sbi,const char * bname)253 static inline int get_bundle_uid(struct hmdfs_sb_info *sbi, const char *bname)
254 {
255 return sbi->user_id * BASE_USER_RANGE + get_bid(bname);
256 }
257
258 #else
259
260 static inline
hmdfs_root_inode_perm_init(struct inode * root_inode)261 void hmdfs_root_inode_perm_init(struct inode *root_inode)
262 {
263 }
264
265 static inline
hmdfs_revert_fsids(const struct cred * old_cred)266 void hmdfs_revert_fsids(const struct cred *old_cred)
267 {
268 }
269
270 static inline
hmdfs_override_dir_id_fs(struct cache_fs_override * or,struct inode * dir,struct dentry * dentry,__u16 * perm)271 int hmdfs_override_dir_id_fs(struct cache_fs_override *or,
272 struct inode *dir,
273 struct dentry *dentry,
274 __u16 *perm)
275 {
276 return 0;
277 }
278
279 static inline
hmdfs_revert_dir_id_fs(struct cache_fs_override * or)280 void hmdfs_revert_dir_id_fs(struct cache_fs_override *or)
281 {
282 }
283
284 static inline
check_and_fixup_ownership(struct inode * parent_inode,struct inode * child)285 void check_and_fixup_ownership(struct inode *parent_inode, struct inode *child)
286 {
287 }
288
289 static inline
hmdfs_override_fsids(bool is_recv_thread)290 const struct cred *hmdfs_override_fsids(bool is_recv_thread)
291 {
292 return ERR_PTR(-ENOTTY);
293 }
294
295 static inline
hmdfs_override_creds(const struct cred * new)296 const struct cred *hmdfs_override_creds(const struct cred *new)
297 {
298 return ERR_PTR(-ENOTTY);
299 }
300
301 static inline
hmdfs_revert_creds(const struct cred * old)302 void hmdfs_revert_creds(const struct cred *old)
303 {
304
305 }
306
307 static inline
check_and_fixup_ownership_remote(struct inode * dir,struct dentry * dentry)308 void check_and_fixup_ownership_remote(struct inode *dir,
309 struct dentry *dentry)
310 {
311 }
312
313 static inline
hmdfs_override_inode_uid(struct inode * inode)314 kuid_t hmdfs_override_inode_uid(struct inode *inode)
315 {
316 return KUIDT_INIT((uid_t)0);
317 }
318
319 static inline
hmdfs_revert_inode_uid(struct inode * inode,kuid_t uid)320 void hmdfs_revert_inode_uid(struct inode *inode, kuid_t uid)
321 {
322 }
323
324 static inline
hmdfs_check_cred(const struct cred * cred)325 void hmdfs_check_cred(const struct cred *cred)
326 {
327 }
328
hmdfs_init_configfs(void)329 static inline int __init hmdfs_init_configfs(void) { return 0; }
hmdfs_exit_configfs(void)330 static inline void hmdfs_exit_configfs(void) {}
331
332 #endif /* CONFIG_HMDFS_FS_PERMISSION */
333
334 #endif
335