android_os_SELinux.cpp revision 81ad284517dc80818cd2f3912fbcf9a7b55df119
1554cb0c290406f5bba34908489db5382a69d0a9arpcraig/*
2554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Copyright (C) 2012 The Android Open Source Project
3554cb0c290406f5bba34908489db5382a69d0a9arpcraig *
4554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Licensed under the Apache License, Version 2.0 (the "License");
5554cb0c290406f5bba34908489db5382a69d0a9arpcraig * you may not use this file except in compliance with the License.
6554cb0c290406f5bba34908489db5382a69d0a9arpcraig * You may obtain a copy of the License at
7554cb0c290406f5bba34908489db5382a69d0a9arpcraig *
8554cb0c290406f5bba34908489db5382a69d0a9arpcraig *      http://www.apache.org/licenses/LICENSE-2.0
9554cb0c290406f5bba34908489db5382a69d0a9arpcraig *
10554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Unless required by applicable law or agreed to in writing, software
11554cb0c290406f5bba34908489db5382a69d0a9arpcraig * distributed under the License is distributed on an "AS IS" BASIS,
12554cb0c290406f5bba34908489db5382a69d0a9arpcraig * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13554cb0c290406f5bba34908489db5382a69d0a9arpcraig * See the License for the specific language governing permissions and
14554cb0c290406f5bba34908489db5382a69d0a9arpcraig * limitations under the License.
15554cb0c290406f5bba34908489db5382a69d0a9arpcraig */
16554cb0c290406f5bba34908489db5382a69d0a9arpcraig
17c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#define LOG_TAG "SELinuxJNI"
18c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include <utils/Log.h>
19c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
20c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include "JNIHelp.h"
21c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include "jni.h"
22c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include "android_runtime/AndroidRuntime.h"
23c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include "selinux/selinux.h"
24554cb0c290406f5bba34908489db5382a69d0a9arpcraig#include "selinux/android.h"
25c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include <errno.h>
26cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root#include <ScopedLocalRef.h>
27cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root#include <ScopedUtfChars.h>
28cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root#include <UniquePtr.h>
29c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
30c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalleynamespace android {
31c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
32cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstruct SecurityContext_Delete {
33cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    void operator()(security_context_t p) const {
34cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        freecon(p);
35cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
36cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root};
37cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Roottypedef UniquePtr<char[], SecurityContext_Delete> Unique_SecurityContext;
38c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
39cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean isSELinuxDisabled = true;
40c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
41cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
42cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: isSELinuxEnabled
43cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose:  checks whether SELinux is enabled/disbaled
44cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters: none
45cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Return value : true (enabled) or false (disabled)
46cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: none
47cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
48cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean isSELinuxEnabled(JNIEnv *env, jobject) {
49c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    return !isSELinuxDisabled;
50cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
51cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root
52cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
53cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: isSELinuxEnforced
54cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: return the current SELinux enforce mode
55cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters: none
56cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Return value: true (enforcing) or false (permissive)
57cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: none
58cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
59cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean isSELinuxEnforced(JNIEnv *env, jobject) {
60c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    return (security_getenforce() == 1) ? true : false;
61cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
62c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
63cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
64cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: setSELinuxEnforce
65cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: set the SE Linux enforcing mode
66cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters: true (enforcing) or false (permissive)
67cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Return value: true (success) or false (fail)
68cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: none
69cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
70cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean setSELinuxEnforce(JNIEnv *env, jobject, jboolean value) {
71cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
72cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
73cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
74c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
75cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int enforce = value ? 1 : 0;
76c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
77c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    return (security_setenforce(enforce) != -1) ? true : false;
78cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
79c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
80cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
81cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: getPeerCon
82cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: retrieves security context of peer socket
83cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters:
84cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *        fileDescriptor: peer socket file as a FileDescriptor object
85cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: jstring representing the security_context of socket or NULL if error
86cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: NullPointerException if fileDescriptor object is NULL
87cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
88cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jstring getPeerCon(JNIEnv *env, jobject, jobject fileDescriptor) {
89cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
90cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
91c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    }
92c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
93cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (fileDescriptor == NULL) {
94cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        jniThrowNullPointerException(env,
95cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root                "Trying to check security context of a null peer socket.");
96cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
97cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
98c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
99c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
100c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    if (env->ExceptionOccurred() != NULL) {
101cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        ALOGE("getPeerCon => getFD for %p failed", fileDescriptor);
102cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
103c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    }
104c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
10581ad284517dc80818cd2f3912fbcf9a7b55df119Richard Haines    security_context_t tmp = NULL;
106cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = getpeercon(fd, &tmp);
107cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    Unique_SecurityContext context(tmp);
108c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
109cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedLocalRef<jstring> contextStr(env, NULL);
110cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (ret != -1) {
111cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        contextStr.reset(env->NewStringUTF(context.get()));
112cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
113c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
11481ad284517dc80818cd2f3912fbcf9a7b55df119Richard Haines    ALOGV("getPeerCon(%d) => %s", fd, context.get());
115cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return contextStr.release();
116cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
117c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
118cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
119cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: setFSCreateCon
120cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: set security context used for creating a new file system object
121cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters:
122cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *       context: security_context_t representing the new context of a file system object,
123cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *                set to NULL to return to the default policy behavior
124cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: true on success, false on error
125cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exception: none
126cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
127cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean setFSCreateCon(JNIEnv *env, jobject, jstring contextStr) {
128cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
129cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
130c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    }
131c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
132cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    UniquePtr<ScopedUtfChars> context;
133cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    const char* context_c_str = NULL;
134cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (contextStr != NULL) {
135cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        context.reset(new ScopedUtfChars(env, contextStr));
136cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        context_c_str = context->c_str();
137cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        if (context_c_str == NULL) {
138cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root            return false;
139cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        }
140cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
141c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
142cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = setfscreatecon(const_cast<char *>(context_c_str));
143c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
144cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("setFSCreateCon(%s) => %d", context_c_str, ret);
145c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
146c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    return (ret == 0) ? true : false;
147cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
148c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
149cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
150cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: setFileCon
151cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose:  set the security context of a file object
152cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters:
153cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *       path: the location of the file system object
154cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *       context: the new security context of the file system object
155cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: true on success, false on error
156cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exception: NullPointerException is thrown if either path or context strign are NULL
157cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
158cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean setFileCon(JNIEnv *env, jobject, jstring pathStr, jstring contextStr) {
159cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
160cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
161c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    }
162c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
163cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars path(env, pathStr);
164cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (path.c_str() == NULL) {
165cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
166c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    }
167c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
168cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars context(env, contextStr);
169cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (context.c_str() == NULL) {
170cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
171cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
172c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
173c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    // GetStringUTFChars returns const char * yet setfilecon needs char *
174cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    char *tmp = const_cast<char *>(context.c_str());
175cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = setfilecon(path.c_str(), tmp);
176c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
177cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("setFileCon(%s, %s) => %d", path.c_str(), context.c_str(), ret);
178c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    return (ret == 0) ? true : false;
179cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
180c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
181cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
182cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: getFileCon
183cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: retrieves the context associated with the given path in the file system
184cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters:
185cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *        path: given path in the file system
186cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns:
187cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *        string representing the security context string of the file object
188cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *        the string may be NULL if an error occured
189cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: NullPointerException if the path object is null
190cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
191cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jstring getFileCon(JNIEnv *env, jobject, jstring pathStr) {
192cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
193cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
194c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    }
195c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
196cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars path(env, pathStr);
197cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (path.c_str() == NULL) {
198cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
199cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
200c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
20181ad284517dc80818cd2f3912fbcf9a7b55df119Richard Haines    security_context_t tmp = NULL;
202cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = getfilecon(path.c_str(), &tmp);
203cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    Unique_SecurityContext context(tmp);
204c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
205cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedLocalRef<jstring> securityString(env, NULL);
206cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (ret != -1) {
207cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        securityString.reset(env->NewStringUTF(context.get()));
208cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
209c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
210cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("getFileCon(%s) => %s", path.c_str(), context.get());
211cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return securityString.release();
212cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
213c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
214cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
215cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: getCon
216cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: Get the context of the current process.
217cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters: none
218cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: a jstring representing the security context of the process,
219cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *          the jstring may be NULL if there was an error
220cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: none
221cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
222cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jstring getCon(JNIEnv *env, jobject) {
223cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
224cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
225cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
226c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
22781ad284517dc80818cd2f3912fbcf9a7b55df119Richard Haines    security_context_t tmp = NULL;
228cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = getcon(&tmp);
229cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    Unique_SecurityContext context(tmp);
230c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
231cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedLocalRef<jstring> securityString(env, NULL);
232cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (ret != -1) {
233cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        securityString.reset(env->NewStringUTF(context.get()));
234cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
235c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
236cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("getCon() => %s", context.get());
237cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return securityString.release();
238cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
239c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
240cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
241cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: getPidCon
242cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: Get the context of a process identified by its pid
243cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters:
244cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *            pid: a jint representing the process
245cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: a jstring representing the security context of the pid,
246cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *          the jstring may be NULL if there was an error
247cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: none
248cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
249cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jstring getPidCon(JNIEnv *env, jobject, jint pid) {
250cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
251cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
252cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
253c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
25481ad284517dc80818cd2f3912fbcf9a7b55df119Richard Haines    security_context_t tmp = NULL;
255cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = getpidcon(static_cast<pid_t>(pid), &tmp);
256cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    Unique_SecurityContext context(tmp);
257c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
258cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedLocalRef<jstring> securityString(env, NULL);
259cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (ret != -1) {
260cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        securityString.reset(env->NewStringUTF(context.get()));
261cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
262c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
263cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("getPidCon(%d) => %s", pid, context.get());
264cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return securityString.release();
265cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
266c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
267cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
268cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: getBooleanNames
269cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: Gets a list of the SELinux boolean names.
270cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters: None
271cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: an array of strings  containing the SELinux boolean names.
272cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *          returns NULL string on error
273cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: None
274cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
275cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jobjectArray getBooleanNames(JNIEnv *env, JNIEnv) {
276cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
277cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
278cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
279c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
280cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    char **list;
281cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int len;
282cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (security_get_boolean_names(&list, &len) == -1) {
283cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return NULL;
284cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
285c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
286cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    jclass stringClass = env->FindClass("java/lang/String");
287cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    jobjectArray stringArray = env->NewObjectArray(len, stringClass, NULL);
288cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    for (int i = 0; i < len; i++) {
289cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        ScopedLocalRef<jstring> obj(env, env->NewStringUTF(list[i]));
290cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        env->SetObjectArrayElement(stringArray, i, obj.get());
291cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        free(list[i]);
292cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
293cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    free(list);
294c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
295cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return stringArray;
296cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
297c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
298cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
299cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: getBooleanValue
300cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: Gets the value for the given SELinux boolean name.
301cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters:
302cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *            String: The name of the SELinux boolean.
303cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: a boolean: (true) boolean is set or (false) it is not.
304cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: None
305cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
306cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean getBooleanValue(JNIEnv *env, jobject, jstring nameStr) {
307cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
308cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
309cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
310c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
311cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (nameStr == NULL) {
312cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
313cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
314c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
315cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars name(env, nameStr);
316cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = security_get_boolean_active(name.c_str());
317c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
318cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("getBooleanValue(%s) => %d", name.c_str(), ret);
319cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return (ret == 1) ? true : false;
320cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
321c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
322cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
323cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: setBooleanNames
324cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: Sets the value for the given SELinux boolean name.
325cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters:
326cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *            String: The name of the SELinux boolean.
327cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *            Boolean: The new value of the SELinux boolean.
328cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: a boolean indicating whether or not the operation succeeded.
329cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: None
330cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
331cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean setBooleanValue(JNIEnv *env, jobject, jstring nameStr, jboolean value) {
332cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
333cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
334cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
335c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
336cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (nameStr == NULL) {
337cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
338cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
339c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
340cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars name(env, nameStr);
341cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = security_set_boolean(name.c_str(), value ? 1 : 0);
342cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (ret) {
343cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
344c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    }
345c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
346cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (security_commit_booleans() == -1) {
347cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
348cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
349c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
350c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    return true;
351cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
352c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
353cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
354cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: checkSELinuxAccess
355cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: Check permissions between two security contexts.
356cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters: subjectContextStr: subject security context as a string
357cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *             objectContextStr: object security context as a string
358cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *             objectClassStr: object's security class name as a string
359cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root *             permissionStr: permission name as a string
360cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: boolean: (true) if permission was granted, (false) otherwise
361cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: None
362cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
363cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean checkSELinuxAccess(JNIEnv *env, jobject, jstring subjectContextStr,
364cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        jstring objectContextStr, jstring objectClassStr, jstring permissionStr) {
365cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
366cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return true;
367cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
368c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
369cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars subjectContext(env, subjectContextStr);
370cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (subjectContext.c_str() == NULL) {
371cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
372cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
373c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
374cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars objectContext(env, objectContextStr);
375cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (objectContext.c_str() == NULL) {
376cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
377cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
378c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
379cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars objectClass(env, objectClassStr);
380cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (objectClass.c_str() == NULL) {
381cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
382cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
383c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
384cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars permission(env, permissionStr);
385cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (permission.c_str() == NULL) {
386cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
387cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
388c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
389cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    char *tmp1 = const_cast<char *>(subjectContext.c_str());
390cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    char *tmp2 = const_cast<char *>(objectContext.c_str());
391cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int accessGranted = selinux_check_access(tmp1, tmp2, objectClass.c_str(), permission.c_str(),
392cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root            NULL);
393c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
394cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("checkSELinuxAccess(%s, %s, %s, %s) => %d", subjectContext.c_str(), objectContext.c_str(),
395cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root            objectClass.c_str(), permission.c_str(), accessGranted);
396c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
397cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return (accessGranted == 0) ? true : false;
398cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
399c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
400cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
401cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Function: native_restorecon
402cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Purpose: restore default SELinux security context
403cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Parameters: pathname: the pathname for the file to be relabeled
404cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Returns: boolean: (true) file label successfully restored, (false) otherwise
405cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * Exceptions: none
406cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
407cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic jboolean native_restorecon(JNIEnv *env, jobject, jstring pathnameStr) {
408cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (isSELinuxDisabled) {
409cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return true;
410cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
411c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
412cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ScopedUtfChars pathname(env, pathnameStr);
413cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    if (pathname.c_str() == NULL) {
414cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        ALOGV("restorecon(%p) => threw exception", pathname);
415cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root        return false;
416cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    }
417554cb0c290406f5bba34908489db5382a69d0a9arpcraig
418cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    int ret = selinux_android_restorecon(pathname.c_str());
419cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    ALOGV("restorecon(%s) => %d", pathname.c_str(), ret);
420cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return (ret == 0);
421cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
422c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
423cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root/*
424cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root * JNI registration.
425cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root */
426cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic JNINativeMethod method_table[] = {
427c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    /* name,                     signature,                    funcPtr */
428c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "checkSELinuxAccess"       , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess },
429c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "getBooleanNames"          , "()[Ljava/lang/String;"                        , (void*)getBooleanNames  },
430c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "getBooleanValue"          , "(Ljava/lang/String;)Z"                        , (void*)getBooleanValue  },
431c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "getContext"               , "()Ljava/lang/String;"                         , (void*)getCon           },
432c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "getFileContext"           , "(Ljava/lang/String;)Ljava/lang/String;"       , (void*)getFileCon       },
433c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "getPeerContext"           , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon       },
434c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "getPidContext"            , "(I)Ljava/lang/String;"                        , (void*)getPidCon        },
435c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "isSELinuxEnforced"        , "()Z"                                          , (void*)isSELinuxEnforced},
436c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "isSELinuxEnabled"         , "()Z"                                          , (void*)isSELinuxEnabled },
437554cb0c290406f5bba34908489db5382a69d0a9arpcraig    { "native_restorecon"        , "(Ljava/lang/String;)Z"                        , (void*)native_restorecon},
438c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "setBooleanValue"          , "(Ljava/lang/String;Z)Z"                       , (void*)setBooleanValue  },
439c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "setFileContext"           , "(Ljava/lang/String;Ljava/lang/String;)Z"      , (void*)setFileCon       },
440c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "setFSCreateContext"       , "(Ljava/lang/String;)Z"                        , (void*)setFSCreateCon   },
441c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    { "setSELinuxEnforce"        , "(Z)Z"                                         , (void*)setSELinuxEnforce},
442cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root};
443c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
444cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootstatic int log_callback(int type, const char *fmt, ...) {
445c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    va_list ap;
446c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    va_start(ap, fmt);
447c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    LOG_PRI_VA(ANDROID_LOG_ERROR, "SELinux", fmt, ap);
448c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    va_end(ap);
449c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    return 0;
450cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
451c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
452cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Rootint register_android_os_SELinux(JNIEnv *env) {
453c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    union selinux_callback cb;
454c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    cb.func_log = log_callback;
455c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    selinux_set_callback(SELINUX_CB_LOG, cb);
456c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
457c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley    isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false;
458c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley
459cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root    return AndroidRuntime::registerNativeMethods(env, "android/os/SELinux", method_table,
460cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root            NELEM(method_table));
461cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root}
462cd19e3f2db333afcf84e2d66d9811e6ccae733a2Kenny Root
463c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley}
464