• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <errno.h>
17 #include <unistd.h>
18 #include <stdio.h>
19 #include "syscall.h"
20 #include "sys/capability.h"
21 
22 static unsigned int __linux_caps_maps[] = {
23 	CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER,
24 	CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_SETPCAP, CAP_NET_BIND_SERVICE,
25 	CAP_NET_BROADCAST, CAP_NET_ADMIN, CAP_NET_RAW, CAP_SYS_PTRACE, CAP_SYS_ADMIN,
26 	CAP_SYS_NICE, CAP_SYS_TIME, CAP_SYS_BOOT};
27 
28 static unsigned int __ohos_caps_maps[] = {
29 	OHOS_CAP_CHOWN, OHOS_CAP_DAC_EXECUTE, OHOS_CAP_DAC_WRITE, OHOS_CAP_DAC_READ_SEARCH, OHOS_CAP_FOWNER, OHOS_CAP_KILL,
30 	OHOS_CAP_SETGID, OHOS_CAP_SETUID, OHOS_CAP_NET_BIND_SERVICE, OHOS_CAP_NET_BROADCAST, OHOS_CAP_NET_ADMIN,
31 	OHOS_CAP_NET_RAW, OHOS_CAP_FS_MOUNT, OHOS_CAP_FS_FORMAT, OHOS_CAP_SCHED_SETPRIORITY,
32 	OHOS_CAP_SET_TIMEOFDAY, OHOS_CAP_CLOCK_SETTIME, OHOS_CAP_CAPSET, OHOS_CAP_REBOOT, OHOS_CAP_SHELL_EXEC};
33 
linux_caps_to_ohos(unsigned int caps)34 static unsigned int linux_caps_to_ohos(unsigned int caps)
35 {
36 	int num = sizeof(__linux_caps_maps) / sizeof(int);
37 	int loop;
38 	unsigned int result = 0;
39 	for (loop = 0; loop < num; loop++) {
40 		if (!((1 << __linux_caps_maps[loop]) & caps)) {
41 			continue;
42 		}
43 
44 		switch (__linux_caps_maps[loop]) {
45 			case CAP_CHOWN:
46 				result |= 1 << OHOS_CAP_CHOWN;
47 				break;
48 			case CAP_DAC_OVERRIDE:
49 				result |= 1 << OHOS_CAP_DAC_EXECUTE;
50 				result |= 1 << OHOS_CAP_DAC_WRITE;
51 				result |= 1 << OHOS_CAP_DAC_READ_SEARCH;
52 				break;
53 			case CAP_DAC_READ_SEARCH:
54 				result |= 1 << OHOS_CAP_DAC_READ_SEARCH;
55 				break;
56 			case CAP_FOWNER:
57 				result |= 1 << OHOS_CAP_FOWNER;
58 				break;
59 			case CAP_KILL:
60 				result |= 1 << OHOS_CAP_KILL;
61 				break;
62 			case CAP_SETGID:
63 				result |= 1 << OHOS_CAP_SETGID;
64 				break;
65 			case CAP_SETUID:
66 				result |= 1 << OHOS_CAP_SETUID;
67 				break;
68 			case CAP_SETPCAP:
69 				result |= 1 << OHOS_CAP_CAPSET;
70 				break;
71 			case CAP_NET_BIND_SERVICE:
72 				result |= 1 << OHOS_CAP_NET_BIND_SERVICE;
73 				break;
74 			case CAP_NET_BROADCAST:
75 				result |= 1 << OHOS_CAP_NET_BROADCAST;
76 				break;
77 			case CAP_NET_ADMIN:
78 				result |= 1 << OHOS_CAP_NET_ADMIN;
79 				break;
80 			case CAP_NET_RAW:
81 				result |= 1 << OHOS_CAP_NET_RAW;
82 				break;
83 			case CAP_SYS_PTRACE:
84 				result |= 1 << OHOS_CAP_SHELL_EXEC;
85 				break;
86 			case CAP_SYS_ADMIN:
87 				result |= 1 << OHOS_CAP_FS_MOUNT;
88 				result |= 1 << OHOS_CAP_FS_FORMAT;
89 				break;
90 			case CAP_SYS_NICE:
91 				result |= 1 << OHOS_CAP_SCHED_SETPRIORITY;
92 				break;
93 			case CAP_SYS_TIME:
94 				result |= 1 << OHOS_CAP_SET_TIMEOFDAY;
95 				result |= 1 << OHOS_CAP_CLOCK_SETTIME;
96 				break;
97 			case CAP_SYS_BOOT:
98 				result |= 1 << OHOS_CAP_REBOOT;
99 				break;
100 			default:
101 				break;
102 		}
103 	}
104 
105 	return result;
106 }
107 
ohos_caps_to_linux(unsigned int caps)108 static unsigned int ohos_caps_to_linux(unsigned int caps)
109 {
110 	int num = sizeof(__ohos_caps_maps) / sizeof(int);
111 	int loop;
112 	unsigned int result = 0;
113 	for (loop = 0; loop < num; loop++) {
114 		if (!((1 << __ohos_caps_maps[loop]) & caps)) {
115 			continue;
116 		}
117 
118 		switch (__ohos_caps_maps[loop]) {
119 			case OHOS_CAP_CHOWN:
120 				result |= 1 << CAP_CHOWN;
121 				break;
122 			case OHOS_CAP_DAC_EXECUTE:
123 			case OHOS_CAP_DAC_WRITE:
124 				result |= 1 << CAP_DAC_OVERRIDE;
125 				break;
126 			case OHOS_CAP_DAC_READ_SEARCH:
127 				result |= 1 << CAP_DAC_READ_SEARCH;
128 				break;
129 			case OHOS_CAP_FOWNER:
130 				result |= 1 << CAP_FOWNER;
131 				break;
132 			case OHOS_CAP_KILL:
133 				result |= 1 << CAP_KILL;
134 				break;
135 			case OHOS_CAP_SETGID:
136 				result |= 1 << CAP_SETGID;
137 				break;
138 			case OHOS_CAP_SETUID:
139 				result |= 1 << CAP_SETUID;
140 				break;
141 			case OHOS_CAP_CAPSET:
142 				result |= 1 << CAP_SETPCAP;
143 				break;
144 			case OHOS_CAP_NET_BIND_SERVICE:
145 				result |= 1 << CAP_NET_BIND_SERVICE;
146 				break;
147 			case OHOS_CAP_NET_BROADCAST:
148 				result |= 1 << CAP_NET_BROADCAST;
149 				break;
150 			case OHOS_CAP_NET_ADMIN:
151 				result |= 1 << CAP_NET_ADMIN;
152 				break;
153 			case OHOS_CAP_NET_RAW:
154 				result |= 1 << CAP_NET_RAW;
155 				break;
156 			case OHOS_CAP_SHELL_EXEC:
157 				result |= 1 << CAP_SYS_PTRACE;
158 				break;
159 			case OHOS_CAP_FS_MOUNT:
160 			case OHOS_CAP_FS_FORMAT:
161 				result |= 1 << CAP_SYS_ADMIN;
162 				break;
163 			case OHOS_CAP_SCHED_SETPRIORITY:
164 				result |= 1 << CAP_SYS_NICE;
165 				break;
166 			case OHOS_CAP_SET_TIMEOFDAY:
167 			case OHOS_CAP_CLOCK_SETTIME:
168 				result |= 1 << CAP_SYS_TIME;
169 				break;
170 			case OHOS_CAP_REBOOT:
171 				result |= 1 << CAP_SYS_BOOT;
172 				break;
173 			default:
174 				break;
175 		}
176 	}
177 
178 	return result;
179 }
180 
linux_capget(cap_user_header_t hdr_ptr,cap_user_data_t data_ptr)181 int linux_capget(cap_user_header_t hdr_ptr, cap_user_data_t data_ptr)
182 {
183 	unsigned int capvalue = 0;
184 
185 	if (hdr_ptr == NULL || data_ptr == NULL) {
186 		errno = EINVAL;
187 		return -1;
188 	}
189 
190 	switch (hdr_ptr->version) {
191 		case _LINUX_CAPABILITY_VERSION_1:
192 		case _LINUX_CAPABILITY_VERSION_2:
193 		case _LINUX_CAPABILITY_VERSION_3:
194 			break;
195 		default:
196 			errno = EINVAL;
197 			return -1;
198 	}
199 
200 	if (syscall(SYS_ohoscapget, hdr_ptr->pid, &capvalue)) {
201 		return -1;
202 	}
203 
204 	data_ptr[0].effective = ohos_caps_to_linux(capvalue);
205 	data_ptr[0].permitted = ohos_caps_to_linux(capvalue);
206 	data_ptr[0].inheritable = ohos_caps_to_linux(capvalue);
207 	return 0;
208 }
209 
linux_capset(cap_user_header_t hdr_ptr,const cap_user_data_t data_ptr)210 int linux_capset(cap_user_header_t hdr_ptr, const cap_user_data_t data_ptr)
211 {
212 	unsigned int capvalue = 0;
213 
214 	if (hdr_ptr == NULL || data_ptr == NULL) {
215 		errno = EINVAL;
216 		return -1;
217 	}
218 
219 	if (hdr_ptr->pid) {
220 		errno = EPERM;
221 		return -1;
222 	}
223 
224 	switch (hdr_ptr->version) {
225 		case _LINUX_CAPABILITY_VERSION_1:
226 		case _LINUX_CAPABILITY_VERSION_2:
227 		case _LINUX_CAPABILITY_VERSION_3:
228 			break;
229 		default:
230 			errno = EINVAL;
231 			return -1;
232 	}
233 
234 	capvalue = linux_caps_to_ohos(data_ptr[0].effective);
235 	return syscall(SYS_ohoscapset, capvalue);
236 }
237 
238 weak_alias(linux_capget, capget);
239 weak_alias(linux_capset, capset);
240 
ohos_capget(pid_t pid,unsigned int * caps)241 int ohos_capget(pid_t pid, unsigned int *caps)
242 {
243 	return syscall(SYS_ohoscapget, pid, caps);
244 }
245 
ohos_capset(unsigned int caps)246 int ohos_capset(unsigned int caps)
247 {
248 	return syscall(SYS_ohoscapset, caps);
249 }
250