diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java index 2773da54b00be..94441cae75677 100644 --- a/core/java/android/os/SELinux.java +++ b/core/java/android/os/SELinux.java @@ -18,9 +18,9 @@ package android.os; import android.util.Slog; -import java.io.IOException; import java.io.File; import java.io.FileDescriptor; +import java.io.IOException; /** * This class provides access to the centralized jni bindings for @@ -78,6 +78,13 @@ public class SELinux { */ public static final native String getPeerContext(FileDescriptor fd); + /** + * Get the security context of a file descriptor of a file. + * @param fd FileDescriptor of a file. + * @return a String representing the file descriptor security context. + */ + public static final native String getFileContext(FileDescriptor fd); + /** * Gets the security context of the current process. * @return a String representing the security context of the current process. diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index a6b29c5f8ce82..061011b41a4b1 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -31,6 +31,7 @@ import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; +import android.os.SELinux; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; @@ -1031,6 +1032,10 @@ public class BatteryStatsHelper { try { ParcelFileDescriptor pfd = service.getStatisticsStream(); if (pfd != null) { + if (false) { + Log.d(TAG, "selinux context: " + + SELinux.getFileContext(pfd.getFileDescriptor())); + } try (FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { byte[] data = readFully(fis, MemoryFile.getSize(pfd.getFileDescriptor())); Parcel parcel = Parcel.obtain(); diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp index 6778b294a93c7..8cb10782310c8 100644 --- a/core/jni/android_os_SELinux.cpp +++ b/core/jni/android_os_SELinux.cpp @@ -60,6 +60,41 @@ static jboolean isSELinuxEnforced(JNIEnv *env, jobject) { return (security_getenforce() == 1) ? true : false; } +static jstring getFdConInner(JNIEnv *env, jobject fileDescriptor, bool isSocket) { + if (isSELinuxDisabled) { + return NULL; + } + + if (fileDescriptor == NULL) { + jniThrowNullPointerException(env, + "Trying to check security context of a null FileDescriptor."); + return NULL; + } + + int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); + if (env->ExceptionCheck()) { + ALOGE("getFdCon => getFD for %p failed", fileDescriptor); + return NULL; + } + + security_context_t tmp = NULL; + int ret; + if (isSocket) { + ret = getpeercon(fd, &tmp); + } else{ + ret = fgetfilecon(fd, &tmp); + } + Unique_SecurityContext context(tmp); + + ScopedLocalRef contextStr(env, NULL); + if (ret != -1) { + contextStr.reset(env->NewStringUTF(context.get())); + } + + ALOGV("getFdCon(%d) => %s", fd, context.get()); + return contextStr.release(); +} + /* * Function: getPeerCon * Purpose: retrieves security context of peer socket @@ -69,33 +104,19 @@ static jboolean isSELinuxEnforced(JNIEnv *env, jobject) { * Exceptions: NullPointerException if fileDescriptor object is NULL */ static jstring getPeerCon(JNIEnv *env, jobject, jobject fileDescriptor) { - if (isSELinuxDisabled) { - return NULL; - } + return getFdConInner(env, fileDescriptor, true); +} - if (fileDescriptor == NULL) { - jniThrowNullPointerException(env, - "Trying to check security context of a null peer socket."); - return NULL; - } - - int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); - if (env->ExceptionCheck()) { - ALOGE("getPeerCon => getFD for %p failed", fileDescriptor); - return NULL; - } - - security_context_t tmp = NULL; - int ret = getpeercon(fd, &tmp); - Unique_SecurityContext context(tmp); - - ScopedLocalRef contextStr(env, NULL); - if (ret != -1) { - contextStr.reset(env->NewStringUTF(context.get())); - } - - ALOGV("getPeerCon(%d) => %s", fd, context.get()); - return contextStr.release(); +/* + * Function: getFdCon + * Purpose: retrieves security context of a file descriptor. + * Parameters: + * fileDescriptor: a FileDescriptor object + * Returns: jstring representing the security_context of socket or NULL if error + * Exceptions: NullPointerException if fileDescriptor object is NULL + */ +static jstring getFdCon(JNIEnv *env, jobject, jobject fileDescriptor) { + return getFdConInner(env, fileDescriptor, false); } /* @@ -326,6 +347,7 @@ static const JNINativeMethod method_table[] = { { "getContext" , "()Ljava/lang/String;" , (void*)getCon }, { "getFileContext" , "(Ljava/lang/String;)Ljava/lang/String;" , (void*)getFileCon }, { "getPeerContext" , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon }, + { "getFileContext" , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getFdCon }, { "getPidContext" , "(I)Ljava/lang/String;" , (void*)getPidCon }, { "isSELinuxEnforced" , "()Z" , (void*)isSELinuxEnforced}, { "isSELinuxEnabled" , "()Z" , (void*)isSELinuxEnabled },