Snap for 7242881 from 41c0644cd269e0ef3b346d4eccbf0e42bc569800 to sdk-release
Change-Id: I55fbfeafe086a86653872f310b122060a977f722
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 0bce6f7..49cb098 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -133,6 +133,7 @@
"Status.cpp",
"TextOutput.cpp",
"Utils.cpp",
+ ":packagemanager_aidl",
":libbinder_aidl",
],
@@ -234,9 +235,6 @@
filegroup {
name: "libbinder_aidl",
srcs: [
- "aidl/android/content/pm/IPackageChangeObserver.aidl",
- "aidl/android/content/pm/IPackageManagerNative.aidl",
- "aidl/android/content/pm/PackageChangeEvent.aidl",
"aidl/android/os/IClientCallback.aidl",
"aidl/android/os/IServiceCallback.aidl",
"aidl/android/os/IServiceManager.aidl",
@@ -245,6 +243,16 @@
path: "aidl",
}
+filegroup {
+ name: "packagemanager_aidl",
+ srcs: [
+ "aidl/android/content/pm/IPackageChangeObserver.aidl",
+ "aidl/android/content/pm/IPackageManagerNative.aidl",
+ "aidl/android/content/pm/PackageChangeEvent.aidl",
+ ],
+ path: "aidl",
+}
+
aidl_interface {
name: "libbinder_aidl_test_stub",
unstable: true,
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index b91d72b..34a474b 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -41,11 +41,12 @@
#include <binder/TextOutput.h>
#include <cutils/ashmem.h>
+#include <cutils/compiler.h>
#include <utils/Flattenable.h>
#include <utils/Log.h>
-#include <utils/misc.h>
-#include <utils/String8.h>
#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/misc.h>
#include <private/binder/binder_module.h>
#include "RpcState.h"
@@ -590,12 +591,14 @@
}
status_t Parcel::writeInterfaceToken(const char16_t* str, size_t len) {
- const IPCThreadState* threadState = IPCThreadState::self();
- writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
- updateWorkSourceRequestHeaderPosition();
- writeInt32(threadState->shouldPropagateWorkSource() ?
- threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
- writeInt32(kHeader);
+ if (CC_LIKELY(!isForRpc())) {
+ const IPCThreadState* threadState = IPCThreadState::self();
+ writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
+ updateWorkSourceRequestHeaderPosition();
+ writeInt32(threadState->shouldPropagateWorkSource() ? threadState->getCallingWorkSourceUid()
+ : IPCThreadState::kUnsetWorkSource);
+ writeInt32(kHeader);
+ }
// currently the interface identification token is just its name as a string
return writeString16(str, len);
@@ -642,31 +645,34 @@
size_t len,
IPCThreadState* threadState) const
{
- // StrictModePolicy.
- int32_t strictPolicy = readInt32();
- if (threadState == nullptr) {
- threadState = IPCThreadState::self();
+ if (CC_LIKELY(!isForRpc())) {
+ // StrictModePolicy.
+ int32_t strictPolicy = readInt32();
+ if (threadState == nullptr) {
+ threadState = IPCThreadState::self();
+ }
+ if ((threadState->getLastTransactionBinderFlags() & IBinder::FLAG_ONEWAY) != 0) {
+ // For one-way calls, the callee is running entirely
+ // disconnected from the caller, so disable StrictMode entirely.
+ // Not only does disk/network usage not impact the caller, but
+ // there's no way to communicate back violations anyway.
+ threadState->setStrictModePolicy(0);
+ } else {
+ threadState->setStrictModePolicy(strictPolicy);
+ }
+ // WorkSource.
+ updateWorkSourceRequestHeaderPosition();
+ int32_t workSource = readInt32();
+ threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
+ // vendor header
+ int32_t header = readInt32();
+ if (header != kHeader) {
+ ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader,
+ header);
+ return false;
+ }
}
- if ((threadState->getLastTransactionBinderFlags() &
- IBinder::FLAG_ONEWAY) != 0) {
- // For one-way calls, the callee is running entirely
- // disconnected from the caller, so disable StrictMode entirely.
- // Not only does disk/network usage not impact the caller, but
- // there's no way to commuicate back any violations anyway.
- threadState->setStrictModePolicy(0);
- } else {
- threadState->setStrictModePolicy(strictPolicy);
- }
- // WorkSource.
- updateWorkSourceRequestHeaderPosition();
- int32_t workSource = readInt32();
- threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
- // vendor header
- int32_t header = readInt32();
- if (header != kHeader) {
- ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader, header);
- return false;
- }
+
// Interface descriptor.
size_t parcel_interface_len;
const char16_t* parcel_interface = readString16Inplace(&parcel_interface_len);
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index 7490b88..b58d919 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -43,6 +43,9 @@
"name": "aidl_integration_test"
},
{
+ "name": "memunreachable_binder_test"
+ },
+ {
"name": "libbinderthreadstateutils_test"
},
{
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index a44c261..8941e49 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -36,11 +36,6 @@
__BEGIN_DECLS
-#ifndef __ANDROID_API__
-#error Android builds must be compiled against a specific API. If this is an \
- android platform host build, you must use libbinder_ndk_host_user.
-#endif
-
typedef uint32_t binder_flags_t;
enum {
/**
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index 05b25e7..b4dc08a 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -32,6 +32,16 @@
__BEGIN_DECLS
+#ifndef __ANDROID_API__
+#error Android builds must be compiled against a specific API. If this is an \
+ android platform host build, you must use libbinder_ndk_host_user.
+#endif
+
+/**
+ * Low-level status types for use in binder. This is the least preferable way to
+ * return an error for binder services (where binder_exception_t should be used,
+ * particularly EX_SERVICE_SPECIFIC).
+ */
enum {
STATUS_OK = 0,
@@ -62,6 +72,10 @@
*/
typedef int32_t binder_status_t;
+/**
+ * Top level exceptions types for Android binder errors, mapping to Java
+ * exceptions. Also see Parcel.java.
+ */
enum {
EX_NONE = 0,
EX_SECURITY = -1,
@@ -170,7 +184,8 @@
/**
* New status with binder_status_t. This is typically for low level failures when a binder_status_t
* is returned by an API on AIBinder or AParcel, and that is to be returned from a method returning
- * an AStatus instance.
+ * an AStatus instance. This is the least preferable way to return errors.
+ * Prefer exceptions (particularly service-specific errors) when possible.
*
* Available since API level 29.
*
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index 5df0012..0668472 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -26,6 +26,9 @@
* This registers the service with the default service manager under this instance name. This does
* not take ownership of binder.
*
+ * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * AIDL services. TODO(b/139325195)
+ *
* \param binder object to register globally with the service manager.
* \param instance identifier of the service. This will be used to lookup the service.
*
@@ -39,6 +42,9 @@
* service is not available This also implicitly calls AIBinder_incStrong (so the caller of this
* function is responsible for calling AIBinder_decStrong).
*
+ * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * AIDL services. TODO(b/139325195)
+ *
* \param instance identifier of the service used to lookup the service.
*/
__attribute__((warn_unused_result)) AIBinder* AServiceManager_checkService(const char* instance);
@@ -48,6 +54,9 @@
* it. This also implicitly calls AIBinder_incStrong (so the caller of this function is responsible
* for calling AIBinder_decStrong).
*
+ * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * AIDL services. TODO(b/139325195)
+ *
* \param instance identifier of the service used to lookup the service.
*/
__attribute__((warn_unused_result)) AIBinder* AServiceManager_getService(const char* instance);
@@ -78,6 +87,9 @@
* This also implicitly calls AIBinder_incStrong (so the caller of this function is responsible
* for calling AIBinder_decStrong).
*
+ * WARNING: when using this API across an APEX boundary, it should only be used with stable
+ * AIDL services. TODO(b/139325195)
+ *
* \param instance identifier of the service used to lookup the service.
*
* \return service if registered, null if not.
diff --git a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
index d54c1a1..6372449 100644
--- a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
+++ b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
@@ -20,9 +20,7 @@
__BEGIN_DECLS
-#if defined(__ANDROID_APEX__) || defined(__ANDROID_VNDK__)
-#error this is only for platform code
-#endif
+#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
/**
* Gets whether or not FDs are allowed by this AParcel
@@ -33,6 +31,9 @@
*/
bool AParcel_getAllowFds(const AParcel*);
+#endif
+
+#if !defined(__ANDROID_APEX__)
/**
* Data written to the parcel will be zero'd before being deleted or realloced.
*
@@ -43,5 +44,6 @@
* \param parcel The parcel to clear associated data from.
*/
void AParcel_markSensitive(const AParcel* parcel);
+#endif
__END_DECLS
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 8d08275..f1db653 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -117,6 +117,7 @@
ABinderProcess_setupPolling; # apex
AIBinder_getCallingSid; # apex
AIBinder_setRequestingSid; # apex
+ AParcel_markSensitive; # llndk
AServiceManager_isDeclared; # apex llndk
AServiceManager_forEachDeclaredInstance; # apex llndk
AServiceManager_registerLazyService; # llndk
@@ -139,7 +140,6 @@
LIBBINDER_NDK_PLATFORM {
global:
AParcel_getAllowFds;
- AParcel_markSensitive;
extern "C++" {
AIBinder_fromPlatformBinder*;
AIBinder_toPlatformBinder*;
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 3899d47..321b422 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -56,6 +56,26 @@
}
}
+/// Interface stability promise
+///
+/// An interface can promise to be a stable vendor interface ([`Vintf`]), or
+/// makes no stability guarantees ([`Local`]). [`Local`] is
+/// currently the default stability.
+pub enum Stability {
+ /// Default stability, visible to other modules in the same compilation
+ /// context (e.g. modules on system.img)
+ Local,
+
+ /// A Vendor Interface Object, which promises to be stable
+ Vintf,
+}
+
+impl Default for Stability {
+ fn default() -> Self {
+ Stability::Local
+ }
+}
+
/// A local service that can be remotable via Binder.
///
/// An object that implement this interface made be made into a Binder service
@@ -94,6 +114,8 @@
pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
+/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
+pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
/// Internal interface of binder local or remote objects for making
/// transactions.
@@ -602,6 +624,23 @@
$interface[$descriptor] {
native: $native($on_transact),
proxy: $proxy {},
+ stability: $crate::Stability::default(),
+ }
+ }
+ };
+
+ {
+ $interface:path[$descriptor:expr] {
+ native: $native:ident($on_transact:path),
+ proxy: $proxy:ident,
+ stability: $stability:expr,
+ }
+ } => {
+ $crate::declare_binder_interface! {
+ $interface[$descriptor] {
+ native: $native($on_transact),
+ proxy: $proxy {},
+ stability: $stability,
}
}
};
@@ -616,12 +655,33 @@
} => {
$crate::declare_binder_interface! {
$interface[$descriptor] {
+ native: $native($on_transact),
+ proxy: $proxy {
+ $($fname: $fty = $finit),*
+ },
+ stability: $crate::Stability::default(),
+ }
+ }
+ };
+
+ {
+ $interface:path[$descriptor:expr] {
+ native: $native:ident($on_transact:path),
+ proxy: $proxy:ident {
+ $($fname:ident: $fty:ty = $finit:expr),*
+ },
+ stability: $stability:expr,
+ }
+ } => {
+ $crate::declare_binder_interface! {
+ $interface[$descriptor] {
@doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
native: $native($on_transact),
@doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
proxy: $proxy {
$($fname: $fty = $finit),*
},
+ stability: $stability,
}
}
};
@@ -635,6 +695,8 @@
proxy: $proxy:ident {
$($fname:ident: $fty:ty = $finit:expr),*
},
+
+ stability: $stability:expr,
}
} => {
#[doc = $proxy_doc]
@@ -669,7 +731,7 @@
impl $native {
/// Create a new binder service.
pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
- let binder = $crate::Binder::new($native(Box::new(inner)));
+ let binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
$crate::Strong::new(Box::new(binder))
}
}
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 5bbd2a3..30928a5 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -107,8 +107,9 @@
pub mod parcel;
pub use crate::binder::{
- FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, Strong,
- TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY,
+ FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable,
+ Stability, Strong, TransactionCode, TransactionFlags, Weak,
+ FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL,
LAST_CALL_TRANSACTION,
};
pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index 185645e..3b3fd08 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-use crate::binder::{AsNative, Interface, InterfaceClassMethods, Remotable, TransactionCode};
+use crate::binder::{AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode};
use crate::error::{status_result, status_t, Result, StatusCode};
use crate::parcel::{Parcel, Serialize};
use crate::proxy::SpIBinder;
@@ -49,11 +49,19 @@
unsafe impl<T: Remotable> Send for Binder<T> {}
impl<T: Remotable> Binder<T> {
- /// Create a new Binder remotable object.
+ /// Create a new Binder remotable object with default stability
///
/// This moves the `rust_object` into an owned [`Box`] and Binder will
/// manage its lifetime.
pub fn new(rust_object: T) -> Binder<T> {
+ Self::new_with_stability(rust_object, Stability::default())
+ }
+
+ /// Create a new Binder remotable object with the given stability
+ ///
+ /// This moves the `rust_object` into an owned [`Box`] and Binder will
+ /// manage its lifetime.
+ pub fn new_with_stability(rust_object: T, stability: Stability) -> Binder<T> {
let class = T::get_class();
let rust_object = Box::into_raw(Box::new(rust_object));
let ibinder = unsafe {
@@ -65,10 +73,12 @@
// ends.
sys::AIBinder_new(class.into(), rust_object as *mut c_void)
};
- Binder {
+ let mut binder = Binder {
ibinder,
rust_object,
- }
+ };
+ binder.mark_stability(stability);
+ binder
}
/// Set the extension of a binder interface. This allows a downstream
@@ -161,6 +171,42 @@
pub fn get_descriptor() -> &'static str {
T::get_descriptor()
}
+
+ /// Mark this binder object with the given stability guarantee
+ fn mark_stability(&mut self, stability: Stability) {
+ match stability {
+ Stability::Local => self.mark_local_stability(),
+ Stability::Vintf => {
+ unsafe {
+ // Safety: Self always contains a valid `AIBinder` pointer, so
+ // we can always call this C API safely.
+ sys::AIBinder_markVintfStability(self.as_native_mut());
+ }
+ }
+ }
+ }
+
+ /// Mark this binder object with local stability, which is vendor if we are
+ /// building for the VNDK and system otherwise.
+ #[cfg(vendor_ndk)]
+ fn mark_local_stability(&mut self) {
+ unsafe {
+ // Safety: Self always contains a valid `AIBinder` pointer, so
+ // we can always call this C API safely.
+ sys::AIBinder_markVendorStability(self.as_native_mut());
+ }
+ }
+
+ /// Mark this binder object with local stability, which is vendor if we are
+ /// building for the VNDK and system otherwise.
+ #[cfg(not(vendor_ndk))]
+ fn mark_local_stability(&mut self) {
+ unsafe {
+ // Safety: Self always contains a valid `AIBinder` pointer, so
+ // we can always call this C API safely.
+ sys::AIBinder_markSystemStability(self.as_native_mut());
+ }
+ }
}
impl<T: Remotable> Interface for Binder<T> {
diff --git a/libs/binder/rust/sys/BinderBindings.hpp b/libs/binder/rust/sys/BinderBindings.hpp
index ef142b5..65fa2ca 100644
--- a/libs/binder/rust/sys/BinderBindings.hpp
+++ b/libs/binder/rust/sys/BinderBindings.hpp
@@ -21,6 +21,7 @@
#include <android/binder_parcel_platform.h>
#include <android/binder_process.h>
#include <android/binder_shell.h>
+#include <android/binder_stability.h>
#include <android/binder_status.h>
namespace android {
@@ -80,6 +81,7 @@
enum {
FLAG_ONEWAY = FLAG_ONEWAY,
FLAG_CLEAR_BUF = FLAG_CLEAR_BUF,
+ FLAG_PRIVATE_LOCAL = FLAG_PRIVATE_LOCAL,
};
} // namespace consts