Merge "Some SELinux specific CTS tests."
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index 5821ec0..4997da2 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -24,10 +24,11 @@
LOCAL_SRC_FILES := \
CtsSecurityJniOnLoad.cpp \
android_security_cts_CharDeviceTest.cpp \
- android_security_cts_NativeCodeTest.cpp
+ android_security_cts_NativeCodeTest.cpp \
+ android_security_cts_SELinuxTest.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog libselinux
include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 7244fc2..6243ac9 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -19,6 +19,7 @@
extern int register_android_security_cts_CharDeviceTest(JNIEnv*);
extern int register_android_security_cts_NativeCodeTest(JNIEnv*);
+extern int register_android_security_cts_SELinuxTest(JNIEnv*);
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
@@ -35,5 +36,9 @@
return JNI_ERR;
}
+ if (register_android_security_cts_SELinuxTest(env)) {
+ return JNI_ERR;
+ }
+
return JNI_VERSION_1_4;
}
diff --git a/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
new file mode 100644
index 0000000..3bee3a5
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <selinux/selinux.h>
+#include <JNIHelp.h>
+#include <ScopedUtfChars.h>
+
+/*
+ * Function: checkSELinuxAccess
+ * Purpose: Check permissions between two security contexts.
+ * Parameters: subjectContextStr: subject security context as a string
+ * objectContextStr: object security context as a string
+ * objectClassStr: object's security class name as a string
+ * permissionStr: permission name as a string
+ * Returns: boolean: (true) if permission was granted, (false) otherwise
+ * Exceptions: NullPointerException if any argument is NULL
+ */
+static jboolean android_security_cts_SELinuxTest_checkSELinuxAccess(JNIEnv *env, jobject, jstring subjectContextStr,
+ jstring objectContextStr, jstring objectClassStr, jstring permissionStr, jstring auxStr) {
+ if (subjectContextStr == NULL || objectContextStr == NULL || objectClassStr == NULL
+ || permissionStr == NULL || auxStr == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return false;
+ }
+
+ ScopedUtfChars subjectContext(env, subjectContextStr);
+ ScopedUtfChars objectContext(env, objectContextStr);
+ ScopedUtfChars objectClass(env, objectClassStr);
+ ScopedUtfChars permission(env, permissionStr);
+ ScopedUtfChars aux(env, auxStr);
+
+ char *tmp1 = const_cast<char *>(subjectContext.c_str());
+ char *tmp2 = const_cast<char *>(objectContext.c_str());
+ char *tmp3 = const_cast<char *>(aux.c_str());
+ int accessGranted = selinux_check_access(tmp1, tmp2, objectClass.c_str(), permission.c_str(), tmp3);
+ return (accessGranted == 0) ? true : false;
+}
+
+
+static JNINativeMethod gMethods[] = {
+ { "checkSELinuxAccess", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
+ (void *) android_security_cts_SELinuxTest_checkSELinuxAccess },
+};
+
+int register_android_security_cts_SELinuxTest(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/security/cts/SELinuxTest");
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/src/android/security/cts/SELinuxTest.java b/tests/tests/security/src/android/security/cts/SELinuxTest.java
new file mode 100644
index 0000000..838eb8a
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SELinuxTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import junit.framework.TestCase;
+
+/**
+ * Verify that the SELinux configuration is sane.
+ */
+public class SELinuxTest extends TestCase {
+
+ static {
+ System.loadLibrary("ctssecurity_jni");
+ }
+
+ public void testMyJni() {
+ try {
+ checkSELinuxAccess(null, null, null, null, null);
+ fail("should have thrown");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+
+ public void testCheckAccessSane() {
+ assertFalse(checkSELinuxAccess("a", "b", "c", "d", "e"));
+ }
+
+ public void testRild() {
+ assertTrue(checkSELinuxAccess("u:r:rild:s0", "u:object_r:rild_prop:s0", "property_service", "set", "ril.ecclist"));
+ }
+
+ public void testZygote() {
+ assertFalse(checkSELinuxAccess("u:r:zygote:s0", "u:object_r:runas_exec:s0", "file", "getattr", "/system/bin/run-as"));
+ // Also check init, just as a sanity check (init is unconfined, so it should pass)
+ assertTrue(checkSELinuxAccess("u:r:init:s0", "u:object_r:runas_exec:s0", "file", "getattr", "/system/bin/run-as"));
+ }
+
+ private static native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm, String extra);
+}