diff options
-rw-r--r-- | core/java/android/os/SELinux.java | 71 | ||||
-rw-r--r-- | core/jni/android_os_SELinux.cpp | 39 | ||||
-rw-r--r-- | services/java/com/android/server/WallpaperManagerService.java | 7 | ||||
-rw-r--r-- | services/java/com/android/server/pm/PackageManagerService.java | 8 |
4 files changed, 124 insertions, 1 deletions
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java index 90cfa37..c05a974 100644 --- a/core/java/android/os/SELinux.java +++ b/core/java/android/os/SELinux.java @@ -1,5 +1,25 @@ +/* + * Copyright (C) 2012 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.os; +import android.util.Slog; + +import java.io.IOException; +import java.io.File; import java.io.FileDescriptor; /** @@ -9,6 +29,8 @@ import java.io.FileDescriptor; */ public class SELinux { + private static final String TAG = "SELinux"; + /** * Determine whether SELinux is disabled or enabled. * @return a boolean indicating whether SELinux is enabled. @@ -102,4 +124,53 @@ public class SELinux { * @return a boolean indicating whether permission was granted. */ public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm); + + /** + * Restores a file to its default SELinux security context. + * If the system is not compiled with SELinux, then {@code true} + * is automatically returned. + * If SELinux is compiled in, but disabled, then {@code true} is + * returned. + * + * @param pathname The pathname of the file to be relabeled. + * @return a boolean indicating whether the relabeling succeeded. + * @exception NullPointerException if the pathname is a null object. + */ + public static boolean restorecon(String pathname) throws NullPointerException { + if (pathname == null) { throw new NullPointerException(); } + return native_restorecon(pathname); + } + + /** + * Restores a file to its default SELinux security context. + * If the system is not compiled with SELinux, then {@code true} + * is automatically returned. + * If SELinux is compiled in, but disabled, then {@code true} is + * returned. + * + * @param pathname The pathname of the file to be relabeled. + * @return a boolean indicating whether the relabeling succeeded. + */ + private static native boolean native_restorecon(String pathname); + + /** + * Restores a file to its default SELinux security context. + * If the system is not compiled with SELinux, then {@code true} + * is automatically returned. + * If SELinux is compiled in, but disabled, then {@code true} is + * returned. + * + * @param file The File object representing the path to be relabeled. + * @return a boolean indicating whether the relabeling succeeded. + * @exception NullPointerException if the file is a null object. + */ + public static boolean restorecon(File file) throws NullPointerException { + try { + return native_restorecon(file.getCanonicalPath()); + } catch (IOException e) { + Slog.e(TAG, "Error getting canonical path. Restorecon failed for " + + file.getPath(), e); + return false; + } + } } diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp index 40443ff..e813c38 100644 --- a/core/jni/android_os_SELinux.cpp +++ b/core/jni/android_os_SELinux.cpp @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2012 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. + */ + #define LOG_TAG "SELinuxJNI" #include <utils/Log.h> @@ -6,6 +22,7 @@ #include "android_runtime/AndroidRuntime.h" #ifdef HAVE_SELINUX #include "selinux/selinux.h" +#include "selinux/android.h" #endif #include <errno.h> @@ -458,6 +475,27 @@ namespace android { } /* + * Function: native_restorecon + * Purpose: restore default SELinux security context + * Parameters: pathname: the pathname for the file to be relabeled + * Returns: boolean: (true) file label successfully restored, (false) otherwise + * Exceptions: none + */ + static jboolean native_restorecon(JNIEnv *env, jobject clazz, jstring pathname) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return true; + + const char *file = const_cast<char *>(env->GetStringUTFChars(pathname, NULL)); + int ret = selinux_android_restorecon(file); + env->ReleaseStringUTFChars(pathname, file); + return (ret == 0); +#else + return true; +#endif + } + + /* * JNI registration. */ static JNINativeMethod method_table[] = { @@ -472,6 +510,7 @@ namespace android { { "getPidContext" , "(I)Ljava/lang/String;" , (void*)getPidCon }, { "isSELinuxEnforced" , "()Z" , (void*)isSELinuxEnforced}, { "isSELinuxEnabled" , "()Z" , (void*)isSELinuxEnabled }, + { "native_restorecon" , "(Ljava/lang/String;)Z" , (void*)native_restorecon}, { "setBooleanValue" , "(Ljava/lang/String;Z)Z" , (void*)setBooleanValue }, { "setFileContext" , "(Ljava/lang/String;Ljava/lang/String;)Z" , (void*)setFileCon }, { "setFSCreateContext" , "(Ljava/lang/String;)Z" , (void*)setFSCreateCon }, diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index d97d335..8a08277 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -45,6 +45,7 @@ import android.os.RemoteException; import android.os.FileObserver; import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; +import android.os.SELinux; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserId; @@ -639,8 +640,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub { FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, -1, -1); } - ParcelFileDescriptor fd = ParcelFileDescriptor.open(new File(dir, WALLPAPER), + File file = new File(dir, WALLPAPER); + ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, MODE_CREATE|MODE_READ_WRITE); + if (!SELinux.restorecon(file)) { + return null; + } wallpaper.name = name; return fd; } catch (FileNotFoundException e) { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 3501e47..8c5a090 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -96,6 +96,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.SystemProperties; @@ -6418,6 +6419,10 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } + if (!SELinux.restorecon(newCodeFile)) { + return false; + } + return true; } } @@ -7399,6 +7404,9 @@ public class PackageManagerService extends IPackageManager.Stub { FileUtils.setPermissions( tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR, -1, -1); + if (!SELinux.restorecon(tmpPackageFile)) { + return null; + } } catch (IOException e) { Slog.e(TAG, "Trouble getting the canoncical path for a temp file."); return null; |