blob: 236ee6123cde454a467b35d87f1b7e33bccada79 [file] [log] [blame]
rpcraig554cb0c2012-07-05 06:41:43 -04001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Stephen Smalleyc07fca32012-01-13 08:31:39 -050017#define LOG_TAG "SELinuxJNI"
18#include <utils/Log.h>
19
Steven Moreland2279b252017-07-19 09:50:45 -070020#include <nativehelper/JNIHelp.h>
Stephen Smalleyc07fca32012-01-13 08:31:39 -050021#include "jni.h"
Andreas Gampeed6b9df2014-11-20 22:02:20 -080022#include "core_jni_helpers.h"
Stephen Smalleyc07fca32012-01-13 08:31:39 -050023#include "selinux/selinux.h"
rpcraig554cb0c2012-07-05 06:41:43 -040024#include "selinux/android.h"
Stephen Smalleyc07fca32012-01-13 08:31:39 -050025#include <errno.h>
Elliott Hughes93bb56e2016-09-11 14:50:12 -070026#include <memory>
Florian Mayerd4db9972019-03-21 13:57:42 +000027#include <atomic>
Steven Moreland2279b252017-07-19 09:50:45 -070028#include <nativehelper/ScopedLocalRef.h>
29#include <nativehelper/ScopedUtfChars.h>
Stephen Smalleyc07fca32012-01-13 08:31:39 -050030
31namespace android {
Florian Mayerd4db9972019-03-21 13:57:42 +000032namespace {
33std::atomic<selabel_handle*> sehandle{nullptr};
34
35selabel_handle* GetSELabelHandle() {
36 selabel_handle* h = sehandle.load();
37 if (h != nullptr) {
38 return h;
39 }
40
41 h = selinux_android_file_context_handle();
42 selabel_handle* expected = nullptr;
43 if (!sehandle.compare_exchange_strong(expected, h)) {
44 selabel_close(h);
45 return sehandle.load();
46 }
47 return h;
48}
49
50}
Stephen Smalleyc07fca32012-01-13 08:31:39 -050051
Kenny Rootcd19e3f2012-10-19 14:15:26 -070052struct SecurityContext_Delete {
53 void operator()(security_context_t p) const {
54 freecon(p);
55 }
56};
Elliott Hughes93bb56e2016-09-11 14:50:12 -070057typedef std::unique_ptr<char[], SecurityContext_Delete> Unique_SecurityContext;
Stephen Smalleyc07fca32012-01-13 08:31:39 -050058
Kenny Rootcd19e3f2012-10-19 14:15:26 -070059static jboolean isSELinuxDisabled = true;
Stephen Smalleyc07fca32012-01-13 08:31:39 -050060
Kenny Rootcd19e3f2012-10-19 14:15:26 -070061/*
62 * Function: isSELinuxEnabled
63 * Purpose: checks whether SELinux is enabled/disbaled
64 * Parameters: none
65 * Return value : true (enabled) or false (disabled)
66 * Exceptions: none
67 */
68static jboolean isSELinuxEnabled(JNIEnv *env, jobject) {
Stephen Smalleyc07fca32012-01-13 08:31:39 -050069 return !isSELinuxDisabled;
Kenny Rootcd19e3f2012-10-19 14:15:26 -070070}
Stephen Smalleyc07fca32012-01-13 08:31:39 -050071
Kenny Rootcd19e3f2012-10-19 14:15:26 -070072/*
73 * Function: isSELinuxEnforced
74 * Purpose: return the current SELinux enforce mode
75 * Parameters: none
76 * Return value: true (enforcing) or false (permissive)
77 * Exceptions: none
78 */
79static jboolean isSELinuxEnforced(JNIEnv *env, jobject) {
Stephen Smalleyc07fca32012-01-13 08:31:39 -050080 return (security_getenforce() == 1) ? true : false;
Kenny Rootcd19e3f2012-10-19 14:15:26 -070081}
Stephen Smalleyc07fca32012-01-13 08:31:39 -050082
Florian Mayerd4db9972019-03-21 13:57:42 +000083static jstring fileSelabelLookup(JNIEnv* env, jobject, jstring pathStr) {
84 if (isSELinuxDisabled) {
85 ALOGE("fileSelabelLookup => SELinux is disabled");
86 return NULL;
87 }
88
89 if (pathStr == NULL) {
90 ALOGE("fileSelabelLookup => got null path.");
91 jniThrowNullPointerException(
92 env, "Trying to get security context of a null path.");
93 return NULL;
94 }
95
96 ScopedUtfChars path(env, pathStr);
97 const char* path_c_str = path.c_str();
98 if (path_c_str == NULL) {
99 ALOGE("fileSelabelLookup => Got null path");
100 jniThrowNullPointerException(
101 env, "Trying to get security context of a null path.");
102 return NULL;
103 }
104
105 auto* selabel_handle = GetSELabelHandle();
106 if (selabel_handle == NULL) {
107 ALOGE("fileSelabelLookup => Failed to get SEHandle");
108 return NULL;
109 }
110
111 security_context_t tmp = NULL;
112 if (selabel_lookup(selabel_handle, &tmp, path_c_str, S_IFREG) != 0) {
113 ALOGE("fileSelabelLookup => selabel_lookup for %s failed: %d", path_c_str, errno);
114 return NULL;
115 }
116
117 Unique_SecurityContext context(tmp);
118 return env->NewStringUTF(context.get());
119}
120
Makoto Onuki9700015b2018-07-27 17:06:30 -0700121static jstring getFdConInner(JNIEnv *env, jobject fileDescriptor, bool isSocket) {
122 if (isSELinuxDisabled) {
123 return NULL;
124 }
125
126 if (fileDescriptor == NULL) {
127 jniThrowNullPointerException(env,
128 "Trying to check security context of a null FileDescriptor.");
129 return NULL;
130 }
131
132 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
133 if (env->ExceptionCheck()) {
134 ALOGE("getFdCon => getFD for %p failed", fileDescriptor);
135 return NULL;
136 }
137
138 security_context_t tmp = NULL;
139 int ret;
140 if (isSocket) {
141 ret = getpeercon(fd, &tmp);
142 } else{
143 ret = fgetfilecon(fd, &tmp);
144 }
145 Unique_SecurityContext context(tmp);
146
147 ScopedLocalRef<jstring> contextStr(env, NULL);
148 if (ret != -1) {
149 contextStr.reset(env->NewStringUTF(context.get()));
150 }
151
152 ALOGV("getFdCon(%d) => %s", fd, context.get());
153 return contextStr.release();
154}
155
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700156/*
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700157 * Function: getPeerCon
158 * Purpose: retrieves security context of peer socket
159 * Parameters:
160 * fileDescriptor: peer socket file as a FileDescriptor object
161 * Returns: jstring representing the security_context of socket or NULL if error
162 * Exceptions: NullPointerException if fileDescriptor object is NULL
163 */
164static jstring getPeerCon(JNIEnv *env, jobject, jobject fileDescriptor) {
Makoto Onuki9700015b2018-07-27 17:06:30 -0700165 return getFdConInner(env, fileDescriptor, true);
166}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500167
Makoto Onuki9700015b2018-07-27 17:06:30 -0700168/*
169 * Function: getFdCon
170 * Purpose: retrieves security context of a file descriptor.
171 * Parameters:
172 * fileDescriptor: a FileDescriptor object
173 * Returns: jstring representing the security_context of socket or NULL if error
174 * Exceptions: NullPointerException if fileDescriptor object is NULL
175 */
176static jstring getFdCon(JNIEnv *env, jobject, jobject fileDescriptor) {
177 return getFdConInner(env, fileDescriptor, false);
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700178}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500179
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700180/*
181 * Function: setFSCreateCon
182 * Purpose: set security context used for creating a new file system object
183 * Parameters:
184 * context: security_context_t representing the new context of a file system object,
185 * set to NULL to return to the default policy behavior
186 * Returns: true on success, false on error
187 * Exception: none
188 */
189static jboolean setFSCreateCon(JNIEnv *env, jobject, jstring contextStr) {
190 if (isSELinuxDisabled) {
191 return false;
192 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500193
Elliott Hughes93bb56e2016-09-11 14:50:12 -0700194 std::unique_ptr<ScopedUtfChars> context;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700195 const char* context_c_str = NULL;
196 if (contextStr != NULL) {
197 context.reset(new ScopedUtfChars(env, contextStr));
198 context_c_str = context->c_str();
199 if (context_c_str == NULL) {
200 return false;
201 }
202 }
203
204 int ret = setfscreatecon(const_cast<char *>(context_c_str));
205
206 ALOGV("setFSCreateCon(%s) => %d", context_c_str, ret);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500207
208 return (ret == 0) ? true : false;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700209}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500210
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700211/*
212 * Function: setFileCon
213 * Purpose: set the security context of a file object
214 * Parameters:
215 * path: the location of the file system object
216 * context: the new security context of the file system object
217 * Returns: true on success, false on error
218 * Exception: NullPointerException is thrown if either path or context strign are NULL
219 */
220static jboolean setFileCon(JNIEnv *env, jobject, jstring pathStr, jstring contextStr) {
221 if (isSELinuxDisabled) {
222 return false;
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500223 }
224
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700225 ScopedUtfChars path(env, pathStr);
226 if (path.c_str() == NULL) {
227 return false;
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500228 }
229
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700230 ScopedUtfChars context(env, contextStr);
231 if (context.c_str() == NULL) {
232 return false;
233 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500234
235 // GetStringUTFChars returns const char * yet setfilecon needs char *
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700236 char *tmp = const_cast<char *>(context.c_str());
237 int ret = setfilecon(path.c_str(), tmp);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500238
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700239 ALOGV("setFileCon(%s, %s) => %d", path.c_str(), context.c_str(), ret);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500240 return (ret == 0) ? true : false;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700241}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500242
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700243/*
244 * Function: getFileCon
245 * Purpose: retrieves the context associated with the given path in the file system
246 * Parameters:
247 * path: given path in the file system
248 * Returns:
249 * string representing the security context string of the file object
250 * the string may be NULL if an error occured
251 * Exceptions: NullPointerException if the path object is null
252 */
253static jstring getFileCon(JNIEnv *env, jobject, jstring pathStr) {
254 if (isSELinuxDisabled) {
255 return NULL;
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500256 }
257
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700258 ScopedUtfChars path(env, pathStr);
259 if (path.c_str() == NULL) {
260 return NULL;
261 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500262
Richard Haines81ad2842013-05-22 15:12:16 +0100263 security_context_t tmp = NULL;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700264 int ret = getfilecon(path.c_str(), &tmp);
265 Unique_SecurityContext context(tmp);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500266
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700267 ScopedLocalRef<jstring> securityString(env, NULL);
268 if (ret != -1) {
269 securityString.reset(env->NewStringUTF(context.get()));
270 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500271
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700272 ALOGV("getFileCon(%s) => %s", path.c_str(), context.get());
273 return securityString.release();
274}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500275
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700276/*
277 * Function: getCon
278 * Purpose: Get the context of the current process.
279 * Parameters: none
280 * Returns: a jstring representing the security context of the process,
281 * the jstring may be NULL if there was an error
282 * Exceptions: none
283 */
284static jstring getCon(JNIEnv *env, jobject) {
285 if (isSELinuxDisabled) {
286 return NULL;
287 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500288
Richard Haines81ad2842013-05-22 15:12:16 +0100289 security_context_t tmp = NULL;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700290 int ret = getcon(&tmp);
291 Unique_SecurityContext context(tmp);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500292
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700293 ScopedLocalRef<jstring> securityString(env, NULL);
294 if (ret != -1) {
295 securityString.reset(env->NewStringUTF(context.get()));
296 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500297
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700298 ALOGV("getCon() => %s", context.get());
299 return securityString.release();
300}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500301
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700302/*
303 * Function: getPidCon
304 * Purpose: Get the context of a process identified by its pid
305 * Parameters:
306 * pid: a jint representing the process
307 * Returns: a jstring representing the security context of the pid,
308 * the jstring may be NULL if there was an error
309 * Exceptions: none
310 */
311static jstring getPidCon(JNIEnv *env, jobject, jint pid) {
312 if (isSELinuxDisabled) {
313 return NULL;
314 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500315
Richard Haines81ad2842013-05-22 15:12:16 +0100316 security_context_t tmp = NULL;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700317 int ret = getpidcon(static_cast<pid_t>(pid), &tmp);
318 Unique_SecurityContext context(tmp);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500319
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700320 ScopedLocalRef<jstring> securityString(env, NULL);
321 if (ret != -1) {
322 securityString.reset(env->NewStringUTF(context.get()));
323 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500324
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700325 ALOGV("getPidCon(%d) => %s", pid, context.get());
326 return securityString.release();
327}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500328
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700329/*
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700330 * Function: checkSELinuxAccess
331 * Purpose: Check permissions between two security contexts.
332 * Parameters: subjectContextStr: subject security context as a string
333 * objectContextStr: object security context as a string
334 * objectClassStr: object's security class name as a string
335 * permissionStr: permission name as a string
336 * Returns: boolean: (true) if permission was granted, (false) otherwise
337 * Exceptions: None
338 */
339static jboolean checkSELinuxAccess(JNIEnv *env, jobject, jstring subjectContextStr,
340 jstring objectContextStr, jstring objectClassStr, jstring permissionStr) {
341 if (isSELinuxDisabled) {
342 return true;
343 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500344
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700345 ScopedUtfChars subjectContext(env, subjectContextStr);
346 if (subjectContext.c_str() == NULL) {
347 return false;
348 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500349
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700350 ScopedUtfChars objectContext(env, objectContextStr);
351 if (objectContext.c_str() == NULL) {
352 return false;
353 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500354
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700355 ScopedUtfChars objectClass(env, objectClassStr);
356 if (objectClass.c_str() == NULL) {
357 return false;
358 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500359
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700360 ScopedUtfChars permission(env, permissionStr);
361 if (permission.c_str() == NULL) {
362 return false;
363 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500364
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700365 char *tmp1 = const_cast<char *>(subjectContext.c_str());
366 char *tmp2 = const_cast<char *>(objectContext.c_str());
367 int accessGranted = selinux_check_access(tmp1, tmp2, objectClass.c_str(), permission.c_str(),
368 NULL);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500369
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700370 ALOGV("checkSELinuxAccess(%s, %s, %s, %s) => %d", subjectContext.c_str(), objectContext.c_str(),
371 objectClass.c_str(), permission.c_str(), accessGranted);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500372
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500373 return (accessGranted == 0) ? true : false;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700374}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500375
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700376/*
377 * Function: native_restorecon
378 * Purpose: restore default SELinux security context
379 * Parameters: pathname: the pathname for the file to be relabeled
380 * Returns: boolean: (true) file label successfully restored, (false) otherwise
381 * Exceptions: none
382 */
Jeff Sharkeyd7460572014-07-06 20:44:55 -0700383static jboolean native_restorecon(JNIEnv *env, jobject, jstring pathnameStr, jint flags) {
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700384 if (isSELinuxDisabled) {
385 return true;
386 }
rpcraig554cb0c2012-07-05 06:41:43 -0400387
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700388 ScopedUtfChars pathname(env, pathnameStr);
389 if (pathname.c_str() == NULL) {
Colin Crossd0696952014-02-06 20:17:48 -0800390 ALOGV("restorecon(%p) => threw exception", pathnameStr);
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700391 return false;
392 }
393
Jeff Sharkeyd7460572014-07-06 20:44:55 -0700394 int ret = selinux_android_restorecon(pathname.c_str(), flags);
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700395 ALOGV("restorecon(%s) => %d", pathname.c_str(), ret);
rpcraig554cb0c2012-07-05 06:41:43 -0400396 return (ret == 0);
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700397}
rpcraig554cb0c2012-07-05 06:41:43 -0400398
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700399/*
400 * JNI registration.
401 */
Daniel Micay76f6a862015-09-19 17:31:01 -0400402static const JNINativeMethod method_table[] = {
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500403 /* name, signature, funcPtr */
404 { "checkSELinuxAccess" , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess },
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500405 { "getContext" , "()Ljava/lang/String;" , (void*)getCon },
406 { "getFileContext" , "(Ljava/lang/String;)Ljava/lang/String;" , (void*)getFileCon },
407 { "getPeerContext" , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon },
Makoto Onuki9700015b2018-07-27 17:06:30 -0700408 { "getFileContext" , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getFdCon },
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500409 { "getPidContext" , "(I)Ljava/lang/String;" , (void*)getPidCon },
410 { "isSELinuxEnforced" , "()Z" , (void*)isSELinuxEnforced},
411 { "isSELinuxEnabled" , "()Z" , (void*)isSELinuxEnabled },
Jeff Sharkeyd7460572014-07-06 20:44:55 -0700412 { "native_restorecon" , "(Ljava/lang/String;I)Z" , (void*)native_restorecon},
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500413 { "setFileContext" , "(Ljava/lang/String;Ljava/lang/String;)Z" , (void*)setFileCon },
414 { "setFSCreateContext" , "(Ljava/lang/String;)Z" , (void*)setFSCreateCon },
Florian Mayerd4db9972019-03-21 13:57:42 +0000415 { "fileSelabelLookup" , "(Ljava/lang/String;)Ljava/lang/String;" , (void*)fileSelabelLookup},
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700416};
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500417
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700418static int log_callback(int type, const char *fmt, ...) {
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500419 va_list ap;
Stephen Smalleye0dda3c2014-01-29 12:55:58 -0500420 int priority;
421
422 switch (type) {
423 case SELINUX_WARNING:
424 priority = ANDROID_LOG_WARN;
425 break;
426 case SELINUX_INFO:
427 priority = ANDROID_LOG_INFO;
428 break;
429 default:
430 priority = ANDROID_LOG_ERROR;
431 break;
432 }
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500433 va_start(ap, fmt);
Stephen Smalleye0dda3c2014-01-29 12:55:58 -0500434 LOG_PRI_VA(priority, "SELinux", fmt, ap);
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500435 va_end(ap);
436 return 0;
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700437}
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500438
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700439int register_android_os_SELinux(JNIEnv *env) {
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500440 union selinux_callback cb;
441 cb.func_log = log_callback;
442 selinux_set_callback(SELINUX_CB_LOG, cb);
443
444 isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false;
445
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800446 return RegisterMethodsOrDie(env, "android/os/SELinux", method_table, NELEM(method_table));
Kenny Rootcd19e3f2012-10-19 14:15:26 -0700447}
448
Stephen Smalleyc07fca32012-01-13 08:31:39 -0500449}