diff options
26 files changed, 855 insertions, 26 deletions
diff --git a/api/current.txt b/api/current.txt index d270ae0..b06a51d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -19290,6 +19290,7 @@ package android.telephony.cdma { public class CdmaCellLocation extends android.telephony.CellLocation { ctor public CdmaCellLocation(); ctor public CdmaCellLocation(android.os.Bundle); + method public static double convertQuartSecToDecDegrees(int); method public void fillInNotifierBundle(android.os.Bundle); method public int getBaseStationId(); method public int getBaseStationLatitude(); diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk index f277339..3e722ea 100644 --- a/cmds/installd/Android.mk +++ b/cmds/installd/Android.mk @@ -34,6 +34,12 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \ libdiskusage +ifeq ($(HAVE_SELINUX),true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_SHARED_LIBRARIES += libselinux +LOCAL_CFLAGS := -DHAVE_SELINUX +endif # HAVE_SELINUX + LOCAL_MODULE := installd LOCAL_MODULE_TAGS := optional diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index dd92bbe..0dd8156 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -17,6 +17,10 @@ #include "installd.h" #include <diskusage/dirsize.h> +#ifdef HAVE_SELINUX +#include <selinux/android.h> +#endif + /* Directory records that are used in execution of commands. */ dir_rec_t android_data_dir; dir_rec_t android_asec_dir; @@ -58,6 +62,15 @@ int install(const char *pkgname, uid_t uid, gid_t gid) unlink(pkgdir); return -errno; } + +#ifdef HAVE_SELINUX + if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) { + LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno)); + unlink(pkgdir); + return -errno; + } +#endif + if (mkdir(libdir, 0755) < 0) { ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno)); unlink(pkgdir); @@ -75,6 +88,16 @@ int install(const char *pkgname, uid_t uid, gid_t gid) unlink(pkgdir); return -errno; } + +#ifdef HAVE_SELINUX + if (selinux_android_setfilecon(libdir, pkgname, AID_SYSTEM) < 0) { + LOGE("cannot setfilecon dir '%s': %s\n", libdir, strerror(errno)); + unlink(libdir); + unlink(pkgdir); + return -errno; + } +#endif + return 0; } @@ -135,6 +158,15 @@ int make_user_data(const char *pkgname, uid_t uid, uid_t persona) unlink(pkgdir); return -errno; } + +#ifdef HAVE_SELINUX + if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) { + LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno)); + unlink(pkgdir); + return -errno; + } +#endif + return 0; } @@ -284,12 +316,18 @@ int protect(char *pkgname, gid_t gid) ALOGE("failed to chgrp '%s': %s\n", pkgpath, strerror(errno)); return -1; } - if (chmod(pkgpath, S_IRUSR|S_IWUSR|S_IRGRP) < 0) { ALOGE("failed to chmod '%s': %s\n", pkgpath, strerror(errno)); return -1; } +#ifdef HAVE_SELINUX + if (selinux_android_setfilecon(pkgpath, pkgname, s.st_uid) < 0) { + LOGE("cannot setfilecon dir '%s': %s\n", pkgpath, strerror(errno)); + return -1; + } +#endif + return 0; } diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java index dd9ea26..3a67cec 100644 --- a/core/java/android/app/Application.java +++ b/core/java/android/app/Application.java @@ -64,11 +64,12 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } /** - * Called when the application is starting, before any other application - * objects have been created. Implementations should be as quick as - * possible (for example using lazy initialization of state) since the time - * spent in this function directly impacts the performance of starting the - * first activity, service, or receiver in a process. + * Called when the application is starting, before any activity, service, + * or receiver objects (excluding content providers) have been created. + * Implementations should be as quick as possible (for example using + * lazy initialization of state) since the time spent in this function + * directly impacts the performance of starting the first activity, + * service, or receiver in a process. * If you override this method, be sure to call super.onCreate(). */ public void onCreate() { diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index c4a4fea..310d033 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -369,6 +369,7 @@ public abstract class ApplicationThreadNative extends Binder case SCHEDULE_LOW_MEMORY_TRANSACTION: { + data.enforceInterface(IApplicationThread.descriptor); scheduleLowMemory(); return true; } diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java new file mode 100644 index 0000000..90cfa37 --- /dev/null +++ b/core/java/android/os/SELinux.java @@ -0,0 +1,105 @@ +package android.os; + +import java.io.FileDescriptor; + +/** + * This class provides access to the centralized jni bindings for + * SELinux interaction. + * {@hide} + */ +public class SELinux { + + /** + * Determine whether SELinux is disabled or enabled. + * @return a boolean indicating whether SELinux is enabled. + */ + public static final native boolean isSELinuxEnabled(); + + /** + * Determine whether SELinux is permissive or enforcing. + * @return a boolean indicating whether SELinux is enforcing. + */ + public static final native boolean isSELinuxEnforced(); + + /** + * Set whether SELinux is permissive or enforcing. + * @param boolean representing whether to set SELinux to enforcing + * @return a boolean representing whether the desired mode was set + */ + public static final native boolean setSELinuxEnforce(boolean value); + + /** + * Sets the security context for newly created file objects. + * @param context a security context given as a String. + * @return a boolean indicating whether the operation succeeded. + */ + public static final native boolean setFSCreateContext(String context); + + /** + * Change the security context of an existing file object. + * @param path representing the path of file object to relabel. + * @param con new security context given as a String. + * @return a boolean indicating whether the operation succeeded. + */ + public static final native boolean setFileContext(String path, String context); + + /** + * Get the security context of a file object. + * @param path the pathname of the file object. + * @return a security context given as a String. + */ + public static final native String getFileContext(String path); + + /** + * Get the security context of a peer socket. + * @param fd FileDescriptor class of the peer socket. + * @return a String representing the peer socket security context. + */ + public static final native String getPeerContext(FileDescriptor fd); + + /** + * Gets the security context of the current process. + * @return a String representing the security context of the current process. + */ + public static final native String getContext(); + + /** + * Gets the security context of a given process id. + * Use of this function is discouraged for Binder transactions. + * Use Binder.getCallingSecctx() instead. + * @param pid an int representing the process id to check. + * @return a String representing the security context of the given pid. + */ + public static final native String getPidContext(int pid); + + /** + * Gets a list of the SELinux boolean names. + * @return an array of strings containing the SELinux boolean names. + */ + public static final native String[] getBooleanNames(); + + /** + * Gets the value for the given SELinux boolean name. + * @param String The name of the SELinux boolean. + * @return a boolean indicating whether the SELinux boolean is set. + */ + public static final native boolean getBooleanValue(String name); + + /** + * Sets the value for the given SELinux boolean name. + * @param String The name of the SELinux boolean. + * @param Boolean The new value of the SELinux boolean. + * @return a boolean indicating whether or not the operation succeeded. + */ + public static final native boolean setBooleanValue(String name, boolean value); + + /** + * Check permissions between two security contexts. + * @param scon The source or subject security context. + * @param tcon The target or object security context. + * @param tclass The object security class name. + * @param perm The permission name. + * @return a boolean indicating whether permission was granted. + */ + public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm); +} diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index f947f95..e2074ec 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -181,6 +181,8 @@ public class WebSettings { private boolean mBlockNetworkImage = false; private boolean mBlockNetworkLoads; private boolean mJavaScriptEnabled = false; + private boolean mAllowUniversalAccessFromFileURLs = true; + private boolean mAllowFileAccessFromFileURLs = true; private boolean mHardwareAccelSkia = false; private boolean mShowVisualIndicator = false; private PluginState mPluginState = PluginState.OFF; @@ -1264,6 +1266,47 @@ public class WebSettings { } /** + * Sets whether JavaScript running in the context of a file scheme URL + * should be allowed to access content from any origin. This includes + * access to content from other file scheme URLs. See + * {@link #setAllowFileAccessFromFileURLs}. To enable the most restrictive, + * and therefore secure policy, this setting should be disabled. + * <p> + * The default value is true. + * + * @param flag whether JavaScript running in the context of a file scheme + * URL should be allowed to access content from any origin + * @hide + */ + public synchronized void setAllowUniversalAccessFromFileURLs(boolean flag) { + if (mAllowUniversalAccessFromFileURLs != flag) { + mAllowUniversalAccessFromFileURLs = flag; + postSync(); + } + } + + /** + * Sets whether JavaScript running in the context of a file scheme URL + * should be allowed to access content from other file scheme URLs. To + * enable the most restrictive, and therefore secure policy, this setting + * should be disabled. Note that the value of this setting is ignored if + * the value of {@link #getAllowUniversalAccessFromFileURLs} is true. + * <p> + * The default value is true. + * + * @param flag whether JavaScript running in the context of a file scheme + * URL should be allowed to access content from other file + * scheme URLs + * @hide + */ + public synchronized void setAllowFileAccessFromFileURLs(boolean flag) { + if (mAllowFileAccessFromFileURLs != flag) { + mAllowFileAccessFromFileURLs = flag; + postSync(); + } + } + + /** * Tell the WebView to use Skia's hardware accelerated rendering path * @param flag True if the WebView should use Skia's hw-accel path * @hide @@ -1500,6 +1543,33 @@ public class WebSettings { } /** + * Gets whether JavaScript running in the context of a file scheme URL can + * access content from any origin. This includes access to content from + * other file scheme URLs. + * + * @return whether JavaScript running in the context of a file scheme URL + * can access content from any origin + * @see #setAllowUniversalAccessFromFileURLs + * @hide + */ + public synchronized boolean getAllowUniversalAccessFromFileURLs() { + return mAllowUniversalAccessFromFileURLs; + } + + /** + * Gets whether JavaScript running in the context of a file scheme URL can + * access content from other file scheme URLs. + * + * @return whether JavaScript running in the context of a file scheme URL + * can access content from other file scheme URLs + * @see #setAllowFileAccessFromFileURLs + * @hide + */ + public synchronized boolean getAllowFileAccessFromFileURLs() { + return mAllowFileAccessFromFileURLs; + } + + /** * Return true if plugins are enabled. * @return True if plugins are enabled. * @deprecated This method has been replaced by {@link #getPluginState} diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java index 77d0c97..96a6428 100644 --- a/core/java/com/android/internal/app/ShutdownThread.java +++ b/core/java/com/android/internal/app/ShutdownThread.java @@ -76,6 +76,8 @@ public final class ShutdownThread extends Thread { private PowerManager.WakeLock mCpuWakeLock; private PowerManager.WakeLock mScreenWakeLock; private Handler mHandler; + + private static AlertDialog sConfirmDialog; private ShutdownThread() { } @@ -108,7 +110,10 @@ public final class ShutdownThread extends Thread { if (confirm) { final CloseDialogReceiver closer = new CloseDialogReceiver(context); - final AlertDialog dialog = new AlertDialog.Builder(context) + if (sConfirmDialog != null) { + sConfirmDialog.dismiss(); + } + sConfirmDialog = new AlertDialog.Builder(context) .setTitle(com.android.internal.R.string.power_off) .setMessage(resourceId) .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() { @@ -118,10 +123,10 @@ public final class ShutdownThread extends Thread { }) .setNegativeButton(com.android.internal.R.string.no, null) .create(); - closer.dialog = dialog; - dialog.setOnDismissListener(closer); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - dialog.show(); + closer.dialog = sConfirmDialog; + sConfirmDialog.setOnDismissListener(closer); + sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); + sConfirmDialog.show(); } else { beginShutdownSequence(context); } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 71c5d26..0b6a3a6 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -66,6 +66,7 @@ LOCAL_SRC_FILES:= \ android_os_MessageQueue.cpp \ android_os_ParcelFileDescriptor.cpp \ android_os_Power.cpp \ + android_os_SELinux.cpp \ android_os_StatFs.cpp \ android_os_SystemClock.cpp \ android_os_SystemProperties.cpp \ @@ -216,7 +217,13 @@ LOCAL_SHARED_LIBRARIES := \ libnfc_ndef \ libusbhost \ libharfbuzz \ - libz \ + libz + +ifeq ($(HAVE_SELINUX),true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_SHARED_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX ifeq ($(USE_OPENGL_RENDERER),true) LOCAL_SHARED_LIBRARIES += libhwui diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 1c0d7cf..31c1120 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -135,6 +135,7 @@ extern int register_android_os_Debug(JNIEnv* env); extern int register_android_os_MessageQueue(JNIEnv* env); extern int register_android_os_ParcelFileDescriptor(JNIEnv *env); extern int register_android_os_Power(JNIEnv *env); +extern int register_android_os_SELinux(JNIEnv* env); extern int register_android_os_StatFs(JNIEnv *env); extern int register_android_os_SystemProperties(JNIEnv *env); extern int register_android_os_SystemClock(JNIEnv* env); @@ -1153,6 +1154,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_MessageQueue), REG_JNI(register_android_os_ParcelFileDescriptor), REG_JNI(register_android_os_Power), + REG_JNI(register_android_os_SELinux), REG_JNI(register_android_os_StatFs), REG_JNI(register_android_os_UEventObserver), REG_JNI(register_android_net_LocalSocketImpl), diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp new file mode 100644 index 0000000..eb99d2b --- /dev/null +++ b/core/jni/android_os_SELinux.cpp @@ -0,0 +1,502 @@ +#define LOG_TAG "SELinuxJNI" +#include <utils/Log.h> + +#include "JNIHelp.h" +#include "jni.h" +#include "android_runtime/AndroidRuntime.h" +#ifdef HAVE_SELINUX +#include "selinux/selinux.h" +#endif +#include <errno.h> + +namespace android { + + static jboolean isSELinuxDisabled = true; + + static void throw_NullPointerException(JNIEnv *env, const char* msg) { + jclass clazz; + clazz = env->FindClass("java/lang/NullPointerException"); + env->ThrowNew(clazz, msg); + } + + /* + * Function: isSELinuxEnabled + * Purpose: checks whether SELinux is enabled/disbaled + * Parameters: none + * Return value : true (enabled) or false (disabled) + * Exceptions: none + */ + static jboolean isSELinuxEnabled(JNIEnv *env, jobject classz) { + + return !isSELinuxDisabled; + } + + /* + * Function: isSELinuxEnforced + * Purpose: return the current SELinux enforce mode + * Parameters: none + * Return value: true (enforcing) or false (permissive) + * Exceptions: none + */ + static jboolean isSELinuxEnforced(JNIEnv *env, jobject clazz) { +#ifdef HAVE_SELINUX + return (security_getenforce() == 1) ? true : false; +#else + return false; +#endif + } + + /* + * Function: setSELinuxEnforce + * Purpose: set the SE Linux enforcing mode + * Parameters: true (enforcing) or false (permissive) + * Return value: true (success) or false (fail) + * Exceptions: none + */ + static jboolean setSELinuxEnforce(JNIEnv *env, jobject clazz, jboolean value) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return false; + + int enforce = (value) ? 1 : 0; + + return (security_setenforce(enforce) != -1) ? true : false; +#else + return false; +#endif + } + + /* + * Function: getPeerCon + * Purpose: retrieves security context of peer socket + * Parameters: + * fileDescriptor: peer socket file as a FileDescriptor object + * Returns: jstring representing the security_context of socket or NULL if error + * Exceptions: NullPointerException if fileDescriptor object is NULL + */ + static jstring getPeerCon(JNIEnv *env, jobject clazz, jobject fileDescriptor) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return NULL; + + if (fileDescriptor == NULL) { + throw_NullPointerException(env, "Trying to check security context of a null peer socket."); + return NULL; + } + + security_context_t context = NULL; + jstring securityString = NULL; + + int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (env->ExceptionOccurred() != NULL) { + LOGE("There was an issue with retrieving the file descriptor"); + goto bail; + } + + if (getpeercon(fd, &context) == -1) + goto bail; + + LOGV("getPeerCon: Successfully retrived context of peer socket '%s'", context); + + securityString = env->NewStringUTF(context); + + bail: + if (context != NULL) + freecon(context); + + return securityString; +#else + return NULL; +#endif + } + + /* + * Function: setFSCreateCon + * Purpose: set security context used for creating a new file system object + * Parameters: + * context: security_context_t representing the new context of a file system object, + * set to NULL to return to the default policy behavior + * Returns: true on success, false on error + * Exception: none + */ + static jboolean setFSCreateCon(JNIEnv *env, jobject clazz, jstring context) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return false; + + char * securityContext = NULL; + const char *constant_securityContext = NULL; + + if (context != NULL) { + constant_securityContext = env->GetStringUTFChars(context, NULL); + + // GetStringUTFChars returns const char * yet setfscreatecon needs char * + securityContext = const_cast<char *>(constant_securityContext); + } + + int ret; + if ((ret = setfscreatecon(securityContext)) == -1) + goto bail; + + LOGV("setFSCreateCon: set new security context to '%s' ", context == NULL ? "default", context); + + bail: + if (constant_securityContext != NULL) + env->ReleaseStringUTFChars(context, constant_securityContext); + + return (ret == 0) ? true : false; +#else + return false; +#endif + } + + /* + * Function: setFileCon + * Purpose: set the security context of a file object + * Parameters: + * path: the location of the file system object + * con: the new security context of the file system object + * Returns: true on success, false on error + * Exception: NullPointerException is thrown if either path or context strign are NULL + */ + static jboolean setFileCon(JNIEnv *env, jobject clazz, jstring path, jstring con) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return false; + + if (path == NULL) { + throw_NullPointerException(env, "Trying to change the security context of a NULL file object."); + return false; + } + + if (con == NULL) { + throw_NullPointerException(env, "Trying to set the security context of a file object with NULL."); + return false; + } + + const char *objectPath = env->GetStringUTFChars(path, NULL); + const char *constant_con = env->GetStringUTFChars(con, NULL); + + // GetStringUTFChars returns const char * yet setfilecon needs char * + char *newCon = const_cast<char *>(constant_con); + + int ret; + if ((ret = setfilecon(objectPath, newCon)) == -1) + goto bail; + + LOGV("setFileCon: Succesfully set security context '%s' for '%s'", newCon, objectPath); + + bail: + env->ReleaseStringUTFChars(path, objectPath); + env->ReleaseStringUTFChars(con, constant_con); + return (ret == 0) ? true : false; +#else + return false; +#endif + } + + /* + * Function: getFileCon + * Purpose: retrieves the context associated with the given path in the file system + * Parameters: + * path: given path in the file system + * Returns: + * string representing the security context string of the file object + * the string may be NULL if an error occured + * Exceptions: NullPointerException if the path object is null + */ + static jstring getFileCon(JNIEnv *env, jobject clazz, jstring path) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return NULL; + + if (path == NULL) { + throw_NullPointerException(env, "Trying to check security context of a null path."); + return NULL; + } + + const char *objectPath = env->GetStringUTFChars(path, NULL); + + security_context_t context = NULL; + jstring securityString = NULL; + + if (getfilecon(objectPath, &context) == -1) + goto bail; + + LOGV("getFileCon: Successfully retrived context '%s' for file '%s'", context, objectPath); + + securityString = env->NewStringUTF(context); + + bail: + if (context != NULL) + freecon(context); + + env->ReleaseStringUTFChars(path, objectPath); + + return securityString; +#else + return NULL; +#endif + } + + /* + * Function: getCon + * Purpose: Get the context of the current process. + * Parameters: none + * Returns: a jstring representing the security context of the process, + * the jstring may be NULL if there was an error + * Exceptions: none + */ + static jstring getCon(JNIEnv *env, jobject clazz) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return NULL; + + security_context_t context = NULL; + jstring securityString = NULL; + + if (getcon(&context) == -1) + goto bail; + + LOGV("getCon: Successfully retrieved context '%s'", context); + + securityString = env->NewStringUTF(context); + + bail: + if (context != NULL) + freecon(context); + + return securityString; +#else + return NULL; +#endif + } + + /* + * Function: getPidCon + * Purpose: Get the context of a process identified by its pid + * Parameters: + * pid: a jint representing the process + * Returns: a jstring representing the security context of the pid, + * the jstring may be NULL if there was an error + * Exceptions: none + */ + static jstring getPidCon(JNIEnv *env, jobject clazz, jint pid) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return NULL; + + security_context_t context = NULL; + jstring securityString = NULL; + + pid_t checkPid = (pid_t)pid; + + if (getpidcon(checkPid, &context) == -1) + goto bail; + + LOGV("getPidCon: Successfully retrived context '%s' for pid '%d'", context, checkPid); + + securityString = env->NewStringUTF(context); + + bail: + if (context != NULL) + freecon(context); + + return securityString; +#else + return NULL; +#endif + } + + /* + * Function: getBooleanNames + * Purpose: Gets a list of the SELinux boolean names. + * Parameters: None + * Returns: an array of strings containing the SELinux boolean names. + * returns NULL string on error + * Exceptions: None + */ + static jobjectArray getBooleanNames(JNIEnv *env, JNIEnv clazz) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return NULL; + + char **list; + int i, len, ret; + jclass stringClass; + jobjectArray stringArray = NULL; + + if (security_get_boolean_names(&list, &len) == -1) + return NULL; + + stringClass = env->FindClass("java/lang/String"); + stringArray = env->NewObjectArray(len, stringClass, env->NewStringUTF("")); + for (i = 0; i < len; i++) { + jstring obj; + obj = env->NewStringUTF(list[i]); + env->SetObjectArrayElement(stringArray, i, obj); + env->DeleteLocalRef(obj); + free(list[i]); + } + free(list); + + return stringArray; +#else + return NULL; +#endif + } + + /* + * Function: getBooleanValue + * Purpose: Gets the value for the given SELinux boolean name. + * Parameters: + * String: The name of the SELinux boolean. + * Returns: a boolean: (true) boolean is set or (false) it is not. + * Exceptions: None + */ + static jboolean getBooleanValue(JNIEnv *env, jobject clazz, jstring name) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return false; + + const char *boolean_name; + int ret; + + if (name == NULL) + return false; + boolean_name = env->GetStringUTFChars(name, NULL); + ret = security_get_boolean_active(boolean_name); + env->ReleaseStringUTFChars(name, boolean_name); + return (ret == 1) ? true : false; +#else + return false; +#endif + } + + /* + * Function: setBooleanNames + * Purpose: Sets the value for the given SELinux boolean name. + * Parameters: + * String: The name of the SELinux boolean. + * Boolean: The new value of the SELinux boolean. + * Returns: a boolean indicating whether or not the operation succeeded. + * Exceptions: None + */ + static jboolean setBooleanValue(JNIEnv *env, jobject clazz, jstring name, jboolean value) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return false; + + const char *boolean_name = NULL; + int ret; + + if (name == NULL) + return false; + boolean_name = env->GetStringUTFChars(name, NULL); + ret = security_set_boolean(boolean_name, (value) ? 1 : 0); + env->ReleaseStringUTFChars(name, boolean_name); + if (ret) + return false; + + if (security_commit_booleans() == -1) + return false; + + return true; +#else + return false; +#endif + } + + /* + * Function: checkSELinuxAccess + * Purpose: Check permissions between two security contexts. + * Parameters: scon: subject security context as a string + * tcon: object security context as a string + * tclass: object's security class name as a string + * perm: permission name as a string + * Returns: boolean: (true) if permission was granted, (false) otherwise + * Exceptions: None + */ + static jboolean checkSELinuxAccess(JNIEnv *env, jobject clazz, jstring scon, jstring tcon, jstring tclass, jstring perm) { +#ifdef HAVE_SELINUX + if (isSELinuxDisabled) + return true; + + int accessGranted = -1; + + const char *const_scon, *const_tcon, *mytclass, *myperm; + char *myscon, *mytcon; + + if (scon == NULL || tcon == NULL || tclass == NULL || perm == NULL) + goto bail; + + const_scon = env->GetStringUTFChars(scon, NULL); + const_tcon = env->GetStringUTFChars(tcon, NULL); + mytclass = env->GetStringUTFChars(tclass, NULL); + myperm = env->GetStringUTFChars(perm, NULL); + + // selinux_check_access needs char* for some + myscon = const_cast<char *>(const_scon); + mytcon = const_cast<char *>(const_tcon); + + accessGranted = selinux_check_access(myscon, mytcon, mytclass, myperm, NULL); + + LOGV("selinux_check_access returned %d", accessGranted); + + env->ReleaseStringUTFChars(scon, const_scon); + env->ReleaseStringUTFChars(tcon, const_tcon); + env->ReleaseStringUTFChars(tclass, mytclass); + env->ReleaseStringUTFChars(perm, myperm); + + bail: + return (accessGranted == 0) ? true : false; + +#else + return true; +#endif + } + + /* + * JNI registration. + */ + static JNINativeMethod method_table[] = { + + /* name, signature, funcPtr */ + { "checkSELinuxAccess" , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess }, + { "getBooleanNames" , "()[Ljava/lang/String;" , (void*)getBooleanNames }, + { "getBooleanValue" , "(Ljava/lang/String;)Z" , (void*)getBooleanValue }, + { "getContext" , "()Ljava/lang/String;" , (void*)getCon }, + { "getFileContext" , "(Ljava/lang/String;)Ljava/lang/String;" , (void*)getFileCon }, + { "getPeerContext" , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon }, + { "getPidContext" , "(I)Ljava/lang/String;" , (void*)getPidCon }, + { "isSELinuxEnforced" , "()Z" , (void*)isSELinuxEnforced}, + { "isSELinuxEnabled" , "()Z" , (void*)isSELinuxEnabled }, + { "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 }, + { "setSELinuxEnforce" , "(Z)Z" , (void*)setSELinuxEnforce}, + }; + + static int log_callback(int type, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + LOG_PRI_VA(ANDROID_LOG_ERROR, "SELinux", fmt, ap); + va_end(ap); + return 0; + } + + int register_android_os_SELinux(JNIEnv *env) { +#ifdef HAVE_SELINUX + union selinux_callback cb; + cb.func_log = log_callback; + selinux_set_callback(SELINUX_CB_LOG, cb); + + isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false; + +#endif + return AndroidRuntime::registerNativeMethods( + env, "android/os/SELinux", + method_table, NELEM(method_table)); + } +} diff --git a/core/tests/coretests/src/android/os/SELinuxTest.java b/core/tests/coretests/src/android/os/SELinuxTest.java new file mode 100644 index 0000000..9b63a6b --- /dev/null +++ b/core/tests/coretests/src/android/os/SELinuxTest.java @@ -0,0 +1,45 @@ +package android.os; + +import android.os.Process; +import android.os.SELinux; +import android.test.AndroidTestCase; +import static junit.framework.Assert.assertEquals; + +public class SELinuxTest extends AndroidTestCase { + + public void testgetFileCon() { + if(SELinux.isSELinuxEnabled() == false) + return; + + String ctx = SELinux.getFileContext("/system/bin/toolbox"); + assertEquals(ctx, "u:object_r:system_file:s0"); + } + + public void testgetCon() { + if(SELinux.isSELinuxEnabled() == false) + return; + + String mycon = SELinux.getContext(); + assertEquals(mycon, "u:r:untrusted_app:s0:c33"); + } + + public void testgetPidCon() { + if(SELinux.isSELinuxEnabled() == false) + return; + + String mycon = SELinux.getPidContext(Process.myPid()); + assertEquals(mycon, "u:r:untrusted_app:s0:c33"); + } + + public void testcheckSELinuxAccess() { + if(SELinux.isSELinuxEnabled() == false) + return; + + String mycon = SELinux.getContext(); + boolean ret; + ret = SELinux.checkSELinuxAccess(mycon, mycon, "process", "fork"); + assertEquals(ret,"true"); + ret = SELinux.checkSELinuxAccess(mycon, mycon, "memprotect", "mmap_zero"); + assertEquals(ret,"true"); + } +} diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 3400e97..2480dec 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1047,10 +1047,11 @@ int32_t Parcel::readExceptionCode() const { int32_t exception_code = readAligned<int32_t>(); if (exception_code == EX_HAS_REPLY_HEADER) { + int32_t header_start = dataPosition(); int32_t header_size = readAligned<int32_t>(); // Skip over fat responses headers. Not used (or propagated) in // native code - setDataPosition(dataPosition() + header_size); + setDataPosition(header_start + header_size); // And fat response headers are currently only used when there are no // exceptions, so return no error: return 0; diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java index e275aa6..d674374 100644 --- a/media/java/android/media/MediaFile.java +++ b/media/java/android/media/MediaFile.java @@ -172,6 +172,7 @@ public class MediaFile { static { addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3); + addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3); addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG); addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV); addFileType("AMR", FILE_TYPE_AMR, "audio/amr"); diff --git a/media/libstagefright/codecs/aacenc/src/aacenc.c b/media/libstagefright/codecs/aacenc/src/aacenc.c index ad2f29a..d1c8621 100644 --- a/media/libstagefright/codecs/aacenc/src/aacenc.c +++ b/media/libstagefright/codecs/aacenc/src/aacenc.c @@ -357,9 +357,9 @@ VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData) if(config.sampleRate%8000 == 0) tmp =480; /* check the bitrate */ - if(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) || + if(config.bitRate!=0 && ((config.bitRate/config.nChannelsOut < 4000) || (config.bitRate/config.nChannelsOut > 160000) || - (config.bitRate > config.sampleRate*6*config.nChannelsOut)) + (config.bitRate > config.sampleRate*6*config.nChannelsOut))) { config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut; diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c index 07b33b7..ccfe883 100644 --- a/media/libstagefright/codecs/aacenc/src/adj_thr.c +++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c @@ -20,13 +20,16 @@ *******************************************************************************/ +/* Include system headers before local headers - the local headers + * redefine __inline, which can mess up definitions in libc headers if + * they happen to use __inline. */ +#include <string.h> #include "basic_op.h" #include "oper_32b.h" #include "adj_thr_data.h" #include "adj_thr.h" #include "qc_data.h" #include "line_pe.h" -#include <string.h> #define minSnrLimit 0x6666 /* 1 dB */ diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index a5e3483..56fe106 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -1460,7 +1460,13 @@ public class DatabaseHelper extends SQLiteOpenHelper { "true".equalsIgnoreCase( SystemProperties.get("ro.com.android.dataroaming", "false")) ? 1 : 0); - + + // Mobile Data default, based on build + loadSetting(stmt, Settings.Secure.MOBILE_DATA, + "true".equalsIgnoreCase( + SystemProperties.get("ro.com.android.mobiledata", + "true")) ? 1 : 0); + loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS, R.bool.def_install_non_market_apps); diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 5425813..540dda4 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -1218,6 +1218,7 @@ class MountService extends IMountService.Stub for(MountServiceBinderListener bl : mListeners) { if (bl.mListener == listener) { mListeners.remove(mListeners.indexOf(bl)); + listener.asBinder().unlinkToDeath(bl, 0); return; } } diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 2a0d2a0..5848cc9 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -1103,6 +1103,8 @@ public class PowerManagerService extends IPowerManager.Stub ? "SCREEN_BRIGHT_BIT " : "") + (((state & SCREEN_ON_BIT) != 0) ? "SCREEN_ON_BIT " : "") + + (((state & BUTTON_BRIGHT_BIT) != 0) + ? "BUTTON_BRIGHT_BIT " : "") + (((state & BATTERY_LOW_BIT) != 0) ? "BATTERY_LOW_BIT " : ""); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 3ae62ad..ce133f0 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -79,7 +79,7 @@ class ServerThread extends Thread { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); - Looper.prepare(); + Looper.prepareMainLooper(); android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index cffb391..6190a63 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1757,7 +1757,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (cr.binding != null && cr.binding.service != null && cr.binding.service.app != null && cr.binding.service.app.lruSeq != mLruSeq) { - updateLruProcessInternalLocked(cr.binding.service.app, oomAdj, + updateLruProcessInternalLocked(cr.binding.service.app, false, updateActivityTime, i+1); } } @@ -1765,7 +1765,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (app.conProviders.size() > 0) { for (ContentProviderRecord cpr : app.conProviders.keySet()) { if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { - updateLruProcessInternalLocked(cpr.proc, oomAdj, + updateLruProcessInternalLocked(cpr.proc, false, updateActivityTime, i+1); } } diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java index e3347cb..c5b1c7b 100644 --- a/services/java/com/android/server/am/UriPermission.java +++ b/services/java/com/android/server/am/UriPermission.java @@ -59,11 +59,11 @@ class UriPermission { if ((modeFlagsToClear&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; - if (readOwners.size() > 0) { + if (writeOwners.size() > 0) { for (UriPermissionOwner r : writeOwners) { r.removeWritePermission(this); } - readOwners.clear(); + writeOwners.clear(); } } } diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java index 84db830..6cfae6a 100644 --- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java +++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java @@ -81,14 +81,26 @@ public class CdmaCellLocation extends CellLocation { } /** - * @return cdma base station latitude, Integer.MAX_VALUE if unknown + * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf) + * It is represented in units of 0.25 seconds and ranges from -1296000 + * to 1296000, both values inclusive (corresponding to a range of -90 + * to +90 degrees). Integer.MAX_VALUE is considered invalid value. + * + * @return cdma base station latitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown */ public int getBaseStationLatitude() { return this.mBaseStationLatitude; } /** - * @return cdma base station longitude, Integer.MAX_VALUE if unknown + * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf) + * It is represented in units of 0.25 seconds and ranges from -2592000 + * to 2592000, both values inclusive (corresponding to a range of -180 + * to +180 degrees). Integer.MAX_VALUE is considered invalid value. + * + * @return cdma base station longitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown */ public int getBaseStationLongitude() { return this.mBaseStationLongitude; @@ -215,6 +227,22 @@ public class CdmaCellLocation extends CellLocation { this.mNetworkId == -1); } + /** + * Converts latitude or longitude from 0.25 seconds (as defined in the + * 3GPP2 C.S0005-A v6.0 standard) to decimal degrees + * + * @param quartSec latitude or longitude in 0.25 seconds units + * @return latitude or longitude in decimal degrees units + * @throws IllegalArgumentException if value is less than -2592000, + * greater than 2592000, or is not a number. + */ + public static double convertQuartSecToDecDegrees(int quartSec) { + if(Double.isNaN(quartSec) || quartSec < -2592000 || quartSec > 2592000){ + // Invalid value + throw new IllegalArgumentException("Invalid coordiante value:" + quartSec); + } + return ((double)quartSec) / (3600 * 4); + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index e1f4c4b..5c95e7d 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -1240,7 +1240,7 @@ public class GSMPhone extends PhoneBase { // If the radio shuts off or resets while one of these // is pending, we need to clean up. - for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) { + for (int i = mPendingMMIs.size() - 1; i >= 0; i--) { if (mPendingMMIs.get(i).isPendingUSSD()) { mPendingMMIs.get(i).onUssdFinishedError(); } diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 7d735ad..22f495a 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -58,7 +58,7 @@ static bool validateFileName(const char* fileName) // The default to use if no other ignore pattern is defined. const char * const gDefaultIgnoreAssets = - "!.svn:!.git:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"; + "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"; // The ignore pattern that can be passed via --ignore-assets in Main.cpp const char * gUserIgnoreAssets = NULL; diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk index cb55a9c..eeddd4b 100644 --- a/tools/aapt/Android.mk +++ b/tools/aapt/Android.mk @@ -29,6 +29,10 @@ LOCAL_SRC_FILES := \ LOCAL_CFLAGS += -Wno-format-y2k +ifeq (darwin,$(HOST_OS)) +LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS +endif + LOCAL_C_INCLUDES += external/expat/lib LOCAL_C_INCLUDES += external/libpng |
