• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <errno.h>
33 #include <unistd.h>
34 #include <stdio.h>
35 #include "syscall.h"
36 #include "sys/capability.h"
37 
38 static unsigned int __linux_caps_maps[] = {
39 	CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER,
40 	CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_SETPCAP, CAP_NET_BIND_SERVICE,
41 	CAP_NET_BROADCAST, CAP_NET_ADMIN, CAP_NET_RAW, CAP_SYS_PTRACE, CAP_SYS_ADMIN,
42 	CAP_SYS_NICE, CAP_SYS_TIME, CAP_SYS_BOOT};
43 
44 static unsigned int __ohos_caps_maps[] = {
45 	OHOS_CAP_CHOWN, OHOS_CAP_DAC_EXECUTE, OHOS_CAP_DAC_WRITE, OHOS_CAP_DAC_READ_SEARCH, OHOS_CAP_FOWNER, OHOS_CAP_KILL,
46 	OHOS_CAP_SETGID, OHOS_CAP_SETUID, OHOS_CAP_NET_BIND_SERVICE, OHOS_CAP_NET_BROADCAST, OHOS_CAP_NET_ADMIN,
47 	OHOS_CAP_NET_RAW, OHOS_CAP_FS_MOUNT, OHOS_CAP_FS_FORMAT, OHOS_CAP_SCHED_SETPRIORITY,
48 	OHOS_CAP_SET_TIMEOFDAY, OHOS_CAP_CLOCK_SETTIME, OHOS_CAP_CAPSET, OHOS_CAP_REBOOT, OHOS_CAP_SHELL_EXEC};
49 
linux_caps_to_ohos(unsigned int caps)50 static unsigned int linux_caps_to_ohos(unsigned int caps)
51 {
52 	int num = sizeof(__linux_caps_maps) / sizeof(int);
53 	int loop;
54 	unsigned int result = 0;
55 	for (loop = 0; loop < num; loop++) {
56 		if (!((1 << __linux_caps_maps[loop]) & caps)) {
57 			continue;
58 		}
59 
60 		switch (__linux_caps_maps[loop]) {
61 			case CAP_CHOWN:
62 				result |= 1 << OHOS_CAP_CHOWN;
63 				break;
64 			case CAP_DAC_OVERRIDE:
65 				result |= 1 << OHOS_CAP_DAC_EXECUTE;
66 				result |= 1 << OHOS_CAP_DAC_WRITE;
67 				result |= 1 << OHOS_CAP_DAC_READ_SEARCH;
68 				break;
69 			case CAP_DAC_READ_SEARCH:
70 				result |= 1 << OHOS_CAP_DAC_READ_SEARCH;
71 				break;
72 			case CAP_FOWNER:
73 				result |= 1 << OHOS_CAP_FOWNER;
74 				break;
75 			case CAP_KILL:
76 				result |= 1 << OHOS_CAP_KILL;
77 				break;
78 			case CAP_SETGID:
79 				result |= 1 << OHOS_CAP_SETGID;
80 				break;
81 			case CAP_SETUID:
82 				result |= 1 << OHOS_CAP_SETUID;
83 				break;
84 			case CAP_SETPCAP:
85 				result |= 1 << OHOS_CAP_CAPSET;
86 				break;
87 			case CAP_NET_BIND_SERVICE:
88 				result |= 1 << OHOS_CAP_NET_BIND_SERVICE;
89 				break;
90 			case CAP_NET_BROADCAST:
91 				result |= 1 << OHOS_CAP_NET_BROADCAST;
92 				break;
93 			case CAP_NET_ADMIN:
94 				result |= 1 << OHOS_CAP_NET_ADMIN;
95 				break;
96 			case CAP_NET_RAW:
97 				result |= 1 << OHOS_CAP_NET_RAW;
98 				break;
99 			case CAP_SYS_PTRACE:
100 				result |= 1 << OHOS_CAP_SHELL_EXEC;
101 				break;
102 			case CAP_SYS_ADMIN:
103 				result |= 1 << OHOS_CAP_FS_MOUNT;
104 				result |= 1 << OHOS_CAP_FS_FORMAT;
105 				break;
106 			case CAP_SYS_NICE:
107 				result |= 1 << OHOS_CAP_SCHED_SETPRIORITY;
108 				break;
109 			case CAP_SYS_TIME:
110 				result |= 1 << OHOS_CAP_SET_TIMEOFDAY;
111 				result |= 1 << OHOS_CAP_CLOCK_SETTIME;
112 				break;
113 			case CAP_SYS_BOOT:
114 				result |= 1 << OHOS_CAP_REBOOT;
115 				break;
116 			default:
117 				break;
118 		}
119 	}
120 
121 	return result;
122 }
123 
ohos_caps_to_linux(unsigned int caps)124 static unsigned int ohos_caps_to_linux(unsigned int caps)
125 {
126 	int num = sizeof(__ohos_caps_maps) / sizeof(int);
127 	int loop;
128 	unsigned int result = 0;
129 	for (loop = 0; loop < num; loop++) {
130 		if (!((1 << __ohos_caps_maps[loop]) & caps)) {
131 			continue;
132 		}
133 
134 		switch (__ohos_caps_maps[loop]) {
135 			case OHOS_CAP_CHOWN:
136 				result |= 1 << CAP_CHOWN;
137 				break;
138 			case OHOS_CAP_DAC_EXECUTE:
139 			case OHOS_CAP_DAC_WRITE:
140 				result |= 1 << CAP_DAC_OVERRIDE;
141 				break;
142 			case OHOS_CAP_DAC_READ_SEARCH:
143 				result |= 1 << CAP_DAC_READ_SEARCH;
144 				break;
145 			case OHOS_CAP_FOWNER:
146 				result |= 1 << CAP_FOWNER;
147 				break;
148 			case OHOS_CAP_KILL:
149 				result |= 1 << CAP_KILL;
150 				break;
151 			case OHOS_CAP_SETGID:
152 				result |= 1 << CAP_SETGID;
153 				break;
154 			case OHOS_CAP_SETUID:
155 				result |= 1 << CAP_SETUID;
156 				break;
157 			case OHOS_CAP_CAPSET:
158 				result |= 1 << CAP_SETPCAP;
159 				break;
160 			case OHOS_CAP_NET_BIND_SERVICE:
161 				result |= 1 << CAP_NET_BIND_SERVICE;
162 				break;
163 			case OHOS_CAP_NET_BROADCAST:
164 				result |= 1 << CAP_NET_BROADCAST;
165 				break;
166 			case OHOS_CAP_NET_ADMIN:
167 				result |= 1 << CAP_NET_ADMIN;
168 				break;
169 			case OHOS_CAP_NET_RAW:
170 				result |= 1 << CAP_NET_RAW;
171 				break;
172 			case OHOS_CAP_SHELL_EXEC:
173 				result |= 1 << CAP_SYS_PTRACE;
174 				break;
175 			case OHOS_CAP_FS_MOUNT:
176 			case OHOS_CAP_FS_FORMAT:
177 				result |= 1 << CAP_SYS_ADMIN;
178 				break;
179 			case OHOS_CAP_SCHED_SETPRIORITY:
180 				result |= 1 << CAP_SYS_NICE;
181 				break;
182 			case OHOS_CAP_SET_TIMEOFDAY:
183 			case OHOS_CAP_CLOCK_SETTIME:
184 				result |= 1 << CAP_SYS_TIME;
185 				break;
186 			case OHOS_CAP_REBOOT:
187 				result |= 1 << CAP_SYS_BOOT;
188 				break;
189 			default:
190 				break;
191 		}
192 	}
193 
194 	return result;
195 }
196 
linux_capget(cap_user_header_t hdr_ptr,cap_user_data_t data_ptr)197 int linux_capget(cap_user_header_t hdr_ptr, cap_user_data_t data_ptr)
198 {
199 	unsigned int capvalue = 0;
200 
201 	if (hdr_ptr == NULL || data_ptr == NULL) {
202 		errno = EINVAL;
203 		return -1;
204 	}
205 
206 	switch (hdr_ptr->version) {
207 		case _LINUX_CAPABILITY_VERSION_1:
208 		case _LINUX_CAPABILITY_VERSION_2:
209 		case _LINUX_CAPABILITY_VERSION_3:
210 			break;
211 		default:
212 			errno = EINVAL;
213 			return -1;
214 	}
215 
216 	if (syscall(SYS_ohoscapget, hdr_ptr->pid, &capvalue)) {
217 		return -1;
218 	}
219 
220 	data_ptr[0].effective = ohos_caps_to_linux(capvalue);
221 	data_ptr[0].permitted = ohos_caps_to_linux(capvalue);
222 	data_ptr[0].inheritable = ohos_caps_to_linux(capvalue);
223 	return 0;
224 }
225 
linux_capset(cap_user_header_t hdr_ptr,const cap_user_data_t data_ptr)226 int linux_capset(cap_user_header_t hdr_ptr, const cap_user_data_t data_ptr)
227 {
228 	unsigned int capvalue = 0;
229 
230 	if (hdr_ptr == NULL || data_ptr == NULL) {
231 		errno = EINVAL;
232 		return -1;
233 	}
234 
235 	if (hdr_ptr->pid) {
236 		errno = EPERM;
237 		return -1;
238 	}
239 
240 	switch (hdr_ptr->version) {
241 		case _LINUX_CAPABILITY_VERSION_1:
242 		case _LINUX_CAPABILITY_VERSION_2:
243 		case _LINUX_CAPABILITY_VERSION_3:
244 			break;
245 		default:
246 			errno = EINVAL;
247 			return -1;
248 	}
249 
250 	capvalue = linux_caps_to_ohos(data_ptr[0].effective);
251 	return syscall(SYS_ohoscapset, capvalue);
252 }
253 
254 weak_alias(linux_capget, capget);
255 weak_alias(linux_capset, capset);
256 
ohos_capget(pid_t pid,unsigned int * caps)257 int ohos_capget(pid_t pid, unsigned int *caps)
258 {
259 	return syscall(SYS_ohoscapget, pid, caps);
260 }
261 
ohos_capset(unsigned int caps)262 int ohos_capset(unsigned int caps)
263 {
264 	return syscall(SYS_ohoscapset, caps);
265 }
266