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