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
19struct 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
68static inline bool is_perm_fix(__u16 perm)
69{
70	return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_FIX;
71}
72
73static inline bool is_perm_mnt(__u16 perm)
74{
75	return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_MNT;
76}
77
78static inline bool is_perm_dfs(__u16 perm)
79{
80	return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_DFS;
81}
82
83static inline bool is_perm_pkg(__u16 perm)
84{
85	return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_PKG;
86}
87
88static inline bool is_perm_other(__u16 perm)
89{
90	return (perm & HMDFS_PERM_MASK) == HMDFS_PERM_OTHER;
91}
92
93static 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
132static inline bool is_data_dir(__u16 perm)
133{
134	return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_DATA;
135}
136
137static inline bool is_service_dir(__u16 perm)
138{
139	return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_SERVICES;
140}
141
142static inline bool is_pkg_dir(__u16 perm)
143{
144	return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_PKG;
145}
146
147static inline bool is_pkg_sub_dir(__u16 perm)
148{
149	return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_PKG_SUB;
150}
151
152static inline bool is_pkg_sub_file(__u16 perm)
153{
154	return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_FILE_PKG_SUB;
155}
156
157static inline bool is_default_dir(__u16 perm)
158{
159	return (perm & HMDFS_DIR_TYPE_MASK) == HMDFS_DIR_DEFAULT;
160}
161
162static 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
172static inline bool is_pkg_auth(__u16 perm)
173{
174	return (perm & AUTH_MASK) == AUTH_PKG;
175}
176
177static inline bool is_system_auth(__u16 perm)
178{
179	return (perm & AUTH_MASK) == AUTH_SYSTEM;
180}
181
182static 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
193static inline void set_inode_gid(struct inode *inode, kgid_t gid)
194{
195	inode->i_gid = gid;
196}
197
198static inline kuid_t get_inode_uid(struct inode *inode)
199{
200	kuid_t uid = inode->i_uid;
201	return uid;
202}
203
204static inline void set_inode_uid(struct inode *inode, kuid_t uid)
205{
206	inode->i_uid = uid;
207}
208
209static 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
217static inline void hmdfs_revert_inode_uid(struct inode *inode, kuid_t uid)
218{
219	set_inode_uid(inode, uid);
220}
221
222static 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
230static inline void hmdfs_revert_creds(const struct cred *old)
231{
232	if (old)
233		revert_creds(old);
234}
235
236static 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
246struct fs_struct *hmdfs_override_fsstruct(struct fs_struct *saved_fs);
247void hmdfs_revert_fsstruct(struct fs_struct *saved_fs,
248			   struct fs_struct *copied_fs);
249const struct cred *hmdfs_override_fsids(bool is_recv_thread);
250const struct cred *hmdfs_override_dir_fsids(struct inode *dir,
251					    struct dentry *dentry, __u16 *perm);
252const struct cred *hmdfs_override_file_fsids(struct inode *dir, __u16 *perm);
253void hmdfs_revert_fsids(const struct cred *old_cred);
254int hmdfs_persist_perm(struct dentry *dentry, __u16 *perm);
255__u16 hmdfs_read_perm(struct inode *inode);
256void hmdfs_root_inode_perm_init(struct inode *root_inode);
257void check_and_fixup_ownership(struct inode *parent_inode, struct inode *child);
258int hmdfs_override_dir_id_fs(struct cache_fs_override *or,
259			struct inode *dir,
260			struct dentry *dentry,
261			__u16 *perm);
262void hmdfs_revert_dir_id_fs(struct cache_fs_override *or);
263void check_and_fixup_ownership_remote(struct inode *dir,
264				      struct inode *dinode,
265				      struct dentry *dentry);
266extern int get_bid(const char *bname);
267extern int __init hmdfs_init_configfs(void);
268extern void hmdfs_exit_configfs(void);
269
270static 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
277static inline
278void hmdfs_root_inode_perm_init(struct inode *root_inode)
279{
280}
281
282static inline
283void hmdfs_revert_fsids(const struct cred *old_cred)
284{
285}
286
287static inline
288int 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
296static inline
297void hmdfs_revert_dir_id_fs(struct cache_fs_override *or)
298{
299}
300
301static inline
302void check_and_fixup_ownership(struct inode *parent_inode, struct inode *child)
303{
304}
305
306static inline
307const struct cred *hmdfs_override_fsids(bool is_recv_thread)
308{
309	return ERR_PTR(-ENOTTY);
310}
311
312static inline
313const struct cred *hmdfs_override_creds(const struct cred *new)
314{
315	return ERR_PTR(-ENOTTY);
316}
317
318static inline
319void hmdfs_revert_creds(const struct cred *old)
320{
321
322}
323
324static inline
325void check_and_fixup_ownership_remote(struct inode *dir,
326				      struct inode *inode,
327				      struct dentry *dentry)
328{
329}
330
331static inline
332kuid_t hmdfs_override_inode_uid(struct inode *inode)
333{
334	return KUIDT_INIT((uid_t)0);
335}
336
337static inline
338void hmdfs_revert_inode_uid(struct inode *inode, kuid_t uid)
339{
340}
341
342static inline
343void hmdfs_check_cred(const struct cred *cred)
344{
345}
346
347static inline int __init hmdfs_init_configfs(void) { return 0; }
348static inline void hmdfs_exit_configfs(void) {}
349
350#endif /* CONFIG_HMDFS_FS_PERMISSION */
351
352#endif
353