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#ifdef HAVE_SELINUX 24c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include "selinux/selinux.h" 25554cb0c290406f5bba34908489db5382a69d0a9arpcraig#include "selinux/android.h" 26c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 27c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#include <errno.h> 28c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 29c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalleynamespace android { 30c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 31c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean isSELinuxDisabled = true; 32c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 33c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static void throw_NullPointerException(JNIEnv *env, const char* msg) { 34c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jclass clazz; 35c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley clazz = env->FindClass("java/lang/NullPointerException"); 36c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ThrowNew(clazz, msg); 37c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 38c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 39c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 40c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: isSELinuxEnabled 41c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: checks whether SELinux is enabled/disbaled 42c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: none 43c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Return value : true (enabled) or false (disabled) 44c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: none 45c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 46c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean isSELinuxEnabled(JNIEnv *env, jobject classz) { 47c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 48c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return !isSELinuxDisabled; 49c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 50c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 51c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 52c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: isSELinuxEnforced 53c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: return the current SELinux enforce mode 54c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: none 55c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Return value: true (enforcing) or false (permissive) 56c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: none 57c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 58c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean isSELinuxEnforced(JNIEnv *env, jobject clazz) { 59c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 60c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return (security_getenforce() == 1) ? true : false; 61c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 62c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 63c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 64c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 65c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 66c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 67c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: setSELinuxEnforce 68c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: set the SE Linux enforcing mode 69c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: true (enforcing) or false (permissive) 70c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Return value: true (success) or false (fail) 71c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: none 72c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 73c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean setSELinuxEnforce(JNIEnv *env, jobject clazz, jboolean value) { 74c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 75c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 76c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 77c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 78c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int enforce = (value) ? 1 : 0; 79c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 80c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return (security_setenforce(enforce) != -1) ? true : false; 81c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 82c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 83c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 84c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 85c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 86c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 87c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: getPeerCon 88c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: retrieves security context of peer socket 89c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: 90c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * fileDescriptor: peer socket file as a FileDescriptor object 91c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: jstring representing the security_context of socket or NULL if error 92c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: NullPointerException if fileDescriptor object is NULL 93c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 94c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jstring getPeerCon(JNIEnv *env, jobject clazz, jobject fileDescriptor) { 95c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 96c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 97c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 98c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 99c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (fileDescriptor == NULL) { 100c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley throw_NullPointerException(env, "Trying to check security context of a null peer socket."); 101c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 102c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 103c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 104c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley security_context_t context = NULL; 105c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jstring securityString = NULL; 106c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 107c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 108c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 109c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (env->ExceptionOccurred() != NULL) { 110365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGE("There was an issue with retrieving the file descriptor"); 111c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 112c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 113c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 114c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (getpeercon(fd, &context) == -1) 115c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 116c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 117365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGV("getPeerCon: Successfully retrived context of peer socket '%s'", context); 118c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 119c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley securityString = env->NewStringUTF(context); 120c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 121c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley bail: 122c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (context != NULL) 123c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley freecon(context); 124c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 125c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return securityString; 126c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 127c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 128c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 129c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 130c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 131c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 132c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: setFSCreateCon 133c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: set security context used for creating a new file system object 134c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: 135c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * context: security_context_t representing the new context of a file system object, 136c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * set to NULL to return to the default policy behavior 137c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: true on success, false on error 138c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exception: none 139c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 140c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean setFSCreateCon(JNIEnv *env, jobject clazz, jstring context) { 141c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 142c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 143c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 144c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 145c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley char * securityContext = NULL; 146c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const char *constant_securityContext = NULL; 147c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 148c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (context != NULL) { 149c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley constant_securityContext = env->GetStringUTFChars(context, NULL); 150c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 151c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley // GetStringUTFChars returns const char * yet setfscreatecon needs char * 152c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley securityContext = const_cast<char *>(constant_securityContext); 153c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 154c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 155c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int ret; 156c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if ((ret = setfscreatecon(securityContext)) == -1) 157c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 158c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 159365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGV("setFSCreateCon: set new security context to '%s' ", context == NULL ? "default", context); 160c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 161c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley bail: 162c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (constant_securityContext != NULL) 163c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(context, constant_securityContext); 164c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 165c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return (ret == 0) ? true : false; 166c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 167c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 168c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 169c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 170c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 171c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 172c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: setFileCon 173c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: set the security context of a file object 174c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: 175c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * path: the location of the file system object 176c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * con: the new security context of the file system object 177c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: true on success, false on error 178c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exception: NullPointerException is thrown if either path or context strign are NULL 179c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 180c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean setFileCon(JNIEnv *env, jobject clazz, jstring path, jstring con) { 181c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 182c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 183c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 184c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 185c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (path == NULL) { 186c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley throw_NullPointerException(env, "Trying to change the security context of a NULL file object."); 187c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 188c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 189c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 190c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (con == NULL) { 191c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley throw_NullPointerException(env, "Trying to set the security context of a file object with NULL."); 192c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 193c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 194c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 195c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const char *objectPath = env->GetStringUTFChars(path, NULL); 196c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const char *constant_con = env->GetStringUTFChars(con, NULL); 197c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 198c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley // GetStringUTFChars returns const char * yet setfilecon needs char * 199c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley char *newCon = const_cast<char *>(constant_con); 200c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 201c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int ret; 202c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if ((ret = setfilecon(objectPath, newCon)) == -1) 203c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 204c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 205365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGV("setFileCon: Succesfully set security context '%s' for '%s'", newCon, objectPath); 206c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 207c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley bail: 208c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(path, objectPath); 209c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(con, constant_con); 210c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return (ret == 0) ? true : false; 211c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 212c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 213c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 214c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 215c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 216c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 217c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: getFileCon 218c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: retrieves the context associated with the given path in the file system 219c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: 220c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * path: given path in the file system 221c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: 222c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * string representing the security context string of the file object 223c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * the string may be NULL if an error occured 224c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: NullPointerException if the path object is null 225c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 226c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jstring getFileCon(JNIEnv *env, jobject clazz, jstring path) { 227c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 228c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 229c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 230c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 231c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (path == NULL) { 232c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley throw_NullPointerException(env, "Trying to check security context of a null path."); 233c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 234c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 235c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 236c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const char *objectPath = env->GetStringUTFChars(path, NULL); 237c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 238c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley security_context_t context = NULL; 239c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jstring securityString = NULL; 240c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 241c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (getfilecon(objectPath, &context) == -1) 242c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 243c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 244365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGV("getFileCon: Successfully retrived context '%s' for file '%s'", context, objectPath); 245c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 246c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley securityString = env->NewStringUTF(context); 247c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 248c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley bail: 249c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (context != NULL) 250c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley freecon(context); 251c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 252c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(path, objectPath); 253c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 254c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return securityString; 255c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 256c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 257c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 258c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 259c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 260c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 261c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: getCon 262c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: Get the context of the current process. 263c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: none 264c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: a jstring representing the security context of the process, 265c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * the jstring may be NULL if there was an error 266c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: none 267c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 268c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jstring getCon(JNIEnv *env, jobject clazz) { 269c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 270c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 271c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 272c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 273c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley security_context_t context = NULL; 274c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jstring securityString = NULL; 275c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 276c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (getcon(&context) == -1) 277c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 278c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 279365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGV("getCon: Successfully retrieved context '%s'", context); 280c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 281c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley securityString = env->NewStringUTF(context); 282c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 283c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley bail: 284c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (context != NULL) 285c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley freecon(context); 286c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 287c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return securityString; 288c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 289c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 290c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 291c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 292c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 293c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 294c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: getPidCon 295c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: Get the context of a process identified by its pid 296c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: 297c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * pid: a jint representing the process 298c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: a jstring representing the security context of the pid, 299c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * the jstring may be NULL if there was an error 300c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: none 301c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 302c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jstring getPidCon(JNIEnv *env, jobject clazz, jint pid) { 303c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 304c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 305c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 306c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 307c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley security_context_t context = NULL; 308c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jstring securityString = NULL; 309c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 310c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley pid_t checkPid = (pid_t)pid; 311c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 312c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (getpidcon(checkPid, &context) == -1) 313c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 314c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 315365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGV("getPidCon: Successfully retrived context '%s' for pid '%d'", context, checkPid); 316c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 317c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley securityString = env->NewStringUTF(context); 318c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 319c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley bail: 320c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (context != NULL) 321c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley freecon(context); 322c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 323c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return securityString; 324c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 325c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 326c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 327c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 328c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 329c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 330c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: getBooleanNames 331c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: Gets a list of the SELinux boolean names. 332c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: None 333c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: an array of strings containing the SELinux boolean names. 334c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * returns NULL string on error 335c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: None 336c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 337c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jobjectArray getBooleanNames(JNIEnv *env, JNIEnv clazz) { 338c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 339c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 340c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 341c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 342c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley char **list; 343c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int i, len, ret; 344c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jclass stringClass; 345c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jobjectArray stringArray = NULL; 346c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 347c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (security_get_boolean_names(&list, &len) == -1) 348c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 349c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 350c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley stringClass = env->FindClass("java/lang/String"); 351c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley stringArray = env->NewObjectArray(len, stringClass, env->NewStringUTF("")); 352c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley for (i = 0; i < len; i++) { 353c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley jstring obj; 354c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley obj = env->NewStringUTF(list[i]); 355c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->SetObjectArrayElement(stringArray, i, obj); 356c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->DeleteLocalRef(obj); 357c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley free(list[i]); 358c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 359c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley free(list); 360c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 361c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return stringArray; 362c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 363c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return NULL; 364c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 365c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 366c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 367c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 368c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: getBooleanValue 369c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: Gets the value for the given SELinux boolean name. 370c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: 371c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * String: The name of the SELinux boolean. 372c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: a boolean: (true) boolean is set or (false) it is not. 373c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: None 374c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 375c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean getBooleanValue(JNIEnv *env, jobject clazz, jstring name) { 376c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 377c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 378c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 379c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 380c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const char *boolean_name; 381c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int ret; 382c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 383c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (name == NULL) 384c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 385c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley boolean_name = env->GetStringUTFChars(name, NULL); 386c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley ret = security_get_boolean_active(boolean_name); 387c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(name, boolean_name); 388c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return (ret == 1) ? true : false; 389c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 390c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 391c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 392c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 393c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 394c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 395c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: setBooleanNames 396c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: Sets the value for the given SELinux boolean name. 397c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: 398c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * String: The name of the SELinux boolean. 399c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Boolean: The new value of the SELinux boolean. 400c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: a boolean indicating whether or not the operation succeeded. 401c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: None 402c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 403c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean setBooleanValue(JNIEnv *env, jobject clazz, jstring name, jboolean value) { 404c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 405c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 406c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 407c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 408c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const char *boolean_name = NULL; 409c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int ret; 410c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 411c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (name == NULL) 412c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 413c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley boolean_name = env->GetStringUTFChars(name, NULL); 414c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley ret = security_set_boolean(boolean_name, (value) ? 1 : 0); 415c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(name, boolean_name); 416c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (ret) 417c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 418c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 419c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (security_commit_booleans() == -1) 420c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 421c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 422c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return true; 423c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 424c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return false; 425c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 426c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 427c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 428c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 429c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Function: checkSELinuxAccess 430c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Purpose: Check permissions between two security contexts. 431c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Parameters: scon: subject security context as a string 432c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * tcon: object security context as a string 433c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * tclass: object's security class name as a string 434c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * perm: permission name as a string 435c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Returns: boolean: (true) if permission was granted, (false) otherwise 436c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * Exceptions: None 437c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 438c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static jboolean checkSELinuxAccess(JNIEnv *env, jobject clazz, jstring scon, jstring tcon, jstring tclass, jstring perm) { 439c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 440c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (isSELinuxDisabled) 441c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return true; 442c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 443c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int accessGranted = -1; 444c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 445c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const char *const_scon, *const_tcon, *mytclass, *myperm; 446c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley char *myscon, *mytcon; 447c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 448c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley if (scon == NULL || tcon == NULL || tclass == NULL || perm == NULL) 449c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley goto bail; 450c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 451c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const_scon = env->GetStringUTFChars(scon, NULL); 452c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley const_tcon = env->GetStringUTFChars(tcon, NULL); 453c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley mytclass = env->GetStringUTFChars(tclass, NULL); 454c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley myperm = env->GetStringUTFChars(perm, NULL); 455c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 456c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley // selinux_check_access needs char* for some 457c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley myscon = const_cast<char *>(const_scon); 458c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley mytcon = const_cast<char *>(const_tcon); 459c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 460c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley accessGranted = selinux_check_access(myscon, mytcon, mytclass, myperm, NULL); 461c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 462365861e3aae9cccdb19b8d4ee375c57e0a431f1eJoshua Brindle ALOGV("selinux_check_access returned %d", accessGranted); 463c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 464c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(scon, const_scon); 465c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(tcon, const_tcon); 466c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(tclass, mytclass); 467c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env->ReleaseStringUTFChars(perm, myperm); 468c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 469c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley bail: 470c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return (accessGranted == 0) ? true : false; 471c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 472c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#else 473c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return true; 474c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 475c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 476c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 477c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* 478554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Function: native_restorecon 479554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Purpose: restore default SELinux security context 480554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Parameters: pathname: the pathname for the file to be relabeled 481554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Returns: boolean: (true) file label successfully restored, (false) otherwise 482554cb0c290406f5bba34908489db5382a69d0a9arpcraig * Exceptions: none 483554cb0c290406f5bba34908489db5382a69d0a9arpcraig */ 484554cb0c290406f5bba34908489db5382a69d0a9arpcraig static jboolean native_restorecon(JNIEnv *env, jobject clazz, jstring pathname) { 485554cb0c290406f5bba34908489db5382a69d0a9arpcraig#ifdef HAVE_SELINUX 486554cb0c290406f5bba34908489db5382a69d0a9arpcraig if (isSELinuxDisabled) 487554cb0c290406f5bba34908489db5382a69d0a9arpcraig return true; 488554cb0c290406f5bba34908489db5382a69d0a9arpcraig 489554cb0c290406f5bba34908489db5382a69d0a9arpcraig const char *file = const_cast<char *>(env->GetStringUTFChars(pathname, NULL)); 490554cb0c290406f5bba34908489db5382a69d0a9arpcraig int ret = selinux_android_restorecon(file); 491554cb0c290406f5bba34908489db5382a69d0a9arpcraig env->ReleaseStringUTFChars(pathname, file); 492554cb0c290406f5bba34908489db5382a69d0a9arpcraig return (ret == 0); 493554cb0c290406f5bba34908489db5382a69d0a9arpcraig#else 494554cb0c290406f5bba34908489db5382a69d0a9arpcraig return true; 495554cb0c290406f5bba34908489db5382a69d0a9arpcraig#endif 496554cb0c290406f5bba34908489db5382a69d0a9arpcraig } 497554cb0c290406f5bba34908489db5382a69d0a9arpcraig 498554cb0c290406f5bba34908489db5382a69d0a9arpcraig /* 499c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley * JNI registration. 500c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley */ 501c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static JNINativeMethod method_table[] = { 502c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 503c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley /* name, signature, funcPtr */ 504c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "checkSELinuxAccess" , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess }, 505c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "getBooleanNames" , "()[Ljava/lang/String;" , (void*)getBooleanNames }, 506c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "getBooleanValue" , "(Ljava/lang/String;)Z" , (void*)getBooleanValue }, 507c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "getContext" , "()Ljava/lang/String;" , (void*)getCon }, 508c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "getFileContext" , "(Ljava/lang/String;)Ljava/lang/String;" , (void*)getFileCon }, 509c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "getPeerContext" , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon }, 510c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "getPidContext" , "(I)Ljava/lang/String;" , (void*)getPidCon }, 511c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "isSELinuxEnforced" , "()Z" , (void*)isSELinuxEnforced}, 512c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "isSELinuxEnabled" , "()Z" , (void*)isSELinuxEnabled }, 513554cb0c290406f5bba34908489db5382a69d0a9arpcraig { "native_restorecon" , "(Ljava/lang/String;)Z" , (void*)native_restorecon}, 514c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "setBooleanValue" , "(Ljava/lang/String;Z)Z" , (void*)setBooleanValue }, 515c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "setFileContext" , "(Ljava/lang/String;Ljava/lang/String;)Z" , (void*)setFileCon }, 516c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "setFSCreateContext" , "(Ljava/lang/String;)Z" , (void*)setFSCreateCon }, 517c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley { "setSELinuxEnforce" , "(Z)Z" , (void*)setSELinuxEnforce}, 518c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley }; 519c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 520c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley static int log_callback(int type, const char *fmt, ...) { 521c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley va_list ap; 522c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley va_start(ap, fmt); 523c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley LOG_PRI_VA(ANDROID_LOG_ERROR, "SELinux", fmt, ap); 524c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley va_end(ap); 525c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return 0; 526c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 527c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 528c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley int register_android_os_SELinux(JNIEnv *env) { 529c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#ifdef HAVE_SELINUX 530c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley union selinux_callback cb; 531c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley cb.func_log = log_callback; 532c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley selinux_set_callback(SELINUX_CB_LOG, cb); 533c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 534c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false; 535c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley 536c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley#endif 537c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley return AndroidRuntime::registerNativeMethods( 538c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley env, "android/os/SELinux", 539c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley method_table, NELEM(method_table)); 540c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley } 541c07fca3831baf4d812dd724f506b4ed23dcc39e0Stephen Smalley} 542