am 753fe8d8: Read Log Permission Test Fixes
Merge commit '753fe8d8ad2e6b88ab26fe405097bb3c22acca4d' into gingerbread
* commit '753fe8d8ad2e6b88ab26fe405097bb3c22acca4d':
Read Log Permission Test Fixes
diff --git a/tests/tests/permission/Android.mk b/tests/tests/permission/Android.mk
index 46e7fb7..c1f7f4d 100644
--- a/tests/tests/permission/Android.mk
+++ b/tests/tests/permission/Android.mk
@@ -21,6 +21,8 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JNI_SHARED_LIBRARIES := libctspermission_jni
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsPermissionTestCases
@@ -30,3 +32,4 @@
include $(BUILD_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/permission/jni/Android.mk b/tests/tests/permission/jni/Android.mk
new file mode 100644
index 0000000..0891a72
--- /dev/null
+++ b/tests/tests/permission/jni/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2010 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libctspermission_jni
+
+# Don't include this package in any configuration by default.
+LOCAL_MODULE_TAGS := optional
+
+# This isn't part of the system, so don't prelink it.
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SRC_FILES := \
+ CtsPermissionsJniOnLoad.cpp \
+ android_permission_cts_FileUtils.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/permission/jni/CtsPermissionsJniOnLoad.cpp b/tests/tests/permission/jni/CtsPermissionsJniOnLoad.cpp
new file mode 100644
index 0000000..fab33bd
--- /dev/null
+++ b/tests/tests/permission/jni/CtsPermissionsJniOnLoad.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 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 <stdio.h>
+
+extern int register_android_permission_cts_FileUtils(JNIEnv*);
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv *env = NULL;
+
+ if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ if (register_android_permission_cts_FileUtils(env)) {
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_4;
+}
diff --git a/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp b/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
new file mode 100644
index 0000000..1666d50
--- /dev/null
+++ b/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 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 <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <grp.h>
+#include <pwd.h>
+
+static jclass gFileStatusClass;
+static jfieldID gFileStatusDevFieldID;
+static jfieldID gFileStatusInoFieldID;
+static jfieldID gFileStatusModeFieldID;
+static jfieldID gFileStatusNlinkFieldID;
+static jfieldID gFileStatusUidFieldID;
+static jfieldID gFileStatusGidFieldID;
+static jfieldID gFileStatusSizeFieldID;
+static jfieldID gFileStatusBlksizeFieldID;
+static jfieldID gFileStatusBlocksFieldID;
+static jfieldID gFileStatusAtimeFieldID;
+static jfieldID gFileStatusMtimeFieldID;
+static jfieldID gFileStatusCtimeFieldID;
+
+/*
+ * Native methods used by
+ * cts/tests/tests/permission/src/android/permission/cts/FileUtils.java
+ *
+ * Copied from hidden API: frameworks/base/core/jni/android_os_FileUtils.cpp
+ */
+
+jboolean android_permission_cts_FileUtils_getFileStatus(JNIEnv* env, jobject thiz,
+ jstring path, jobject fileStatus, jboolean statLinks)
+{
+ const char* pathStr = env->GetStringUTFChars(path, NULL);
+ jboolean ret = false;
+ struct stat s;
+
+ int res = statLinks == true ? lstat(pathStr, &s) : stat(pathStr, &s);
+
+ if (res == 0) {
+ ret = true;
+ if (fileStatus != NULL) {
+ env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
+ env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
+ env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
+ env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
+ env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
+ env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
+ env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
+ env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
+ env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
+ env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
+ env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
+ env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
+ }
+ }
+
+ env->ReleaseStringUTFChars(path, pathStr);
+
+ return ret;
+}
+
+jstring android_permission_cts_FileUtils_getUserName(JNIEnv* env, jobject thiz,
+ jint uid)
+{
+ struct passwd *pwd = getpwuid(uid);
+ return env->NewStringUTF(pwd->pw_name);
+}
+
+jstring android_permission_cts_FileUtils_getGroupName(JNIEnv* env, jobject thiz,
+ jint gid)
+{
+ struct group *grp = getgrgid(gid);
+ return env->NewStringUTF(grp->gr_name);
+}
+
+static JNINativeMethod gMethods[] = {
+ { "getFileStatus", "(Ljava/lang/String;Landroid/permission/cts/FileUtils$FileStatus;Z)Z",
+ (void *) android_permission_cts_FileUtils_getFileStatus },
+ { "getUserName", "(I)Ljava/lang/String;",
+ (void *) android_permission_cts_FileUtils_getUserName },
+ { "getGroupName", "(I)Ljava/lang/String;",
+ (void *) android_permission_cts_FileUtils_getGroupName },
+};
+
+int register_android_permission_cts_FileUtils(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/permission/cts/FileUtils");
+
+ gFileStatusClass = env->FindClass("android/permission/cts/FileUtils$FileStatus");
+ gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
+ gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
+ gFileStatusModeFieldID = env->GetFieldID(gFileStatusClass, "mode", "I");
+ gFileStatusNlinkFieldID = env->GetFieldID(gFileStatusClass, "nlink", "I");
+ gFileStatusUidFieldID = env->GetFieldID(gFileStatusClass, "uid", "I");
+ gFileStatusGidFieldID = env->GetFieldID(gFileStatusClass, "gid", "I");
+ gFileStatusSizeFieldID = env->GetFieldID(gFileStatusClass, "size", "J");
+ gFileStatusBlksizeFieldID = env->GetFieldID(gFileStatusClass, "blksize", "I");
+ gFileStatusBlocksFieldID = env->GetFieldID(gFileStatusClass, "blocks", "J");
+ gFileStatusAtimeFieldID = env->GetFieldID(gFileStatusClass, "atime", "J");
+ gFileStatusMtimeFieldID = env->GetFieldID(gFileStatusClass, "mtime", "J");
+ gFileStatusCtimeFieldID = env->GetFieldID(gFileStatusClass, "ctime", "J");
+
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/permission/src/android/permission/cts/FileUtils.java b/tests/tests/permission/src/android/permission/cts/FileUtils.java
new file mode 100644
index 0000000..5a869de
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/FileUtils.java
@@ -0,0 +1,83 @@
+package android.permission.cts;
+
+/*
+ * Copyright (C) 2010 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.
+ */
+
+/** Bits and pieces copied from hidden API of android.os.FileUtils. */
+public class FileUtils {
+
+ public static final int S_IFSOCK = 0140000;
+ public static final int S_IFLNK = 0120000;
+ public static final int S_IFREG = 0100000;
+ public static final int S_IFBLK = 0060000;
+ public static final int S_IFDIR = 0040000;
+ public static final int S_IFCHR = 0020000;
+ public static final int S_IFIFO = 0010000;
+
+ public static final int S_ISUID = 0004000;
+ public static final int S_ISGID = 0002000;
+ public static final int S_ISVTX = 0001000;
+
+ public static final int S_IRUSR = 00400;
+ public static final int S_IWUSR = 00200;
+ public static final int S_IXUSR = 00100;
+
+ public static final int S_IRGRP = 00040;
+ public static final int S_IWGRP = 00020;
+ public static final int S_IXGRP = 00010;
+
+ public static final int S_IROTH = 00004;
+ public static final int S_IWOTH = 00002;
+ public static final int S_IXOTH = 00001;
+
+ static {
+ System.loadLibrary("ctspermission_jni");
+ }
+
+ public static class FileStatus {
+
+ public int dev;
+ public int ino;
+ public int mode;
+ public int nlink;
+ public int uid;
+ public int gid;
+ public int rdev;
+ public long size;
+ public int blksize;
+ public long blocks;
+ public long atime;
+ public long mtime;
+ public long ctime;
+
+ public boolean hasModeFlag(int flag) {
+ return (mode & flag) == flag;
+ }
+ }
+
+ /**
+ * @param path of the file to stat
+ * @param status object to set the fields on
+ * @param statLinks or don't stat links (lstat vs stat)
+ * @return whether or not we were able to stat the file
+ */
+ public native static boolean getFileStatus(String path, FileStatus status, boolean statLinks);
+
+ public native static String getUserName(int uid);
+
+ public native static String getGroupName(int gid);
+
+}
diff --git a/tests/tests/permission/src/android/permission/cts/NoReadLogsPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoReadLogsPermissionTest.java
index db57927..256a15c 100644
--- a/tests/tests/permission/src/android/permission/cts/NoReadLogsPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoReadLogsPermissionTest.java
@@ -16,14 +16,16 @@
package android.permission.cts;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
+import android.permission.cts.FileUtils.FileStatus;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
/**
* Verify the read system log require specific permissions.
*/
@@ -37,12 +39,12 @@
* @throws IOException
*/
@MediumTest
- public void testSetMicrophoneMute() throws IOException {
+ public void testLogcat() throws IOException {
Process logcatProc = null;
BufferedReader reader = null;
try {
logcatProc = Runtime.getRuntime().exec(new String[]
- {"logcat", "-d", "AndroidRuntime:E :" + LOGTAG + ":V *:S" });
+ {"logcat", "-d", "AndroidRuntime:E " + LOGTAG + ":V *:S" });
Log.d(LOGTAG, "no read logs permission test");
reader = new BufferedReader(new InputStreamReader(logcatProc.getInputStream()));
@@ -54,6 +56,7 @@
log.append(line);
log.append(separator);
}
+
// no permission get empty log
assertEquals(0, log.length());
@@ -63,4 +66,23 @@
}
}
}
+
+ public void testLogFilePermissions() {
+ File logDir = new File("/dev/log");
+ File[] logFiles = logDir.listFiles();
+ assertTrue("Where are the log files? Please check that they are not world readable.",
+ logFiles.length > 0);
+
+ FileStatus status = new FileStatus();
+ for (File log : logFiles) {
+ if (FileUtils.getFileStatus(log.getAbsolutePath(), status, false)) {
+ assertEquals("Log file " + log.getAbsolutePath() + " should have user root.",
+ 0, status.uid);
+ assertTrue("Log file " + log.getAbsolutePath() + " should have group log.",
+ "log".equals(FileUtils.getGroupName(status.gid)));
+ assertFalse("Log file " + log.getAbsolutePath() + " should not be world readable.",
+ status.hasModeFlag(FileUtils.S_IROTH));
+ }
+ }
+ }
}