Skip to content
Snippets Groups Projects
Commit e22f560d authored by Jooyung Han's avatar Jooyung Han
Browse files

Fix VintfObject to use vintf

VintfObject is a TestApi class and used by CTS tests and EDI collectors.
Previously, it used libvintf to open VINTF data from device which caused
SEPolicy error because
- CTS tests and EDI collectors are "apps"
- VINTF data needs to load files unavailable to apps.

In this change, VintfObject uses "instrumentation" to get VINTF data by
calling /system/bin/vintf under shell identity.

Bug: 338278029
Bug: 317747397
Test: atest SELinuxNeverallowRulesTest
Test: VintfDeviceInfo/VintfFilesCollector work
Change-Id: I43a54827a1d82cfaf573753c5c5862425843a099
parent 9c6959af
No related branches found
No related tags found
No related merge requests found
......@@ -17,8 +17,11 @@
package android.os;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.ActivityThread;
import java.io.IOException;
import java.util.Map;
/**
......@@ -113,5 +116,20 @@ public class VintfObject {
@TestApi
public static native Long getTargetFrameworkCompatibilityMatrixVersion();
/**
* Executes a shell command using shell user identity, and return the standard output in string.
*
* @hide
*/
private static @Nullable String runShellCommand(@NonNull String command) throws IOException {
var activityThread = ActivityThread.currentActivityThread();
var instrumentation = activityThread.getInstrumentation();
var automation = instrumentation.getUiAutomation();
var pfd = automation.executeShellCommand(command);
try (var is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
return new String(is.readAllBytes());
}
}
private VintfObject() {}
}
......@@ -32,6 +32,8 @@ static jmethodID gHashMapInit;
static jmethodID gHashMapPut;
static jclass gLongClazz;
static jmethodID gLongValueOf;
static jclass gVintfObjectClazz;
static jmethodID gRunCommand;
namespace android {
......@@ -47,6 +49,56 @@ using vintf::VintfObject;
using vintf::Vndk;
using vintf::CheckFlags::ENABLE_ALL_CHECKS;
// Instead of VintfObject::GetXxx(), we construct
// HalManifest/CompatibilityMatrix objects by calling `vintf` through
// UiAutomation.executeShellCommand() so that the commands are executed
// using shell identity. Otherwise, we would need to allow "apps" to access
// files like apex-info-list.xml which we don't want to open to apps.
// This is okay because VintfObject is @TestApi and only used in CTS tests.
static std::string runCmd(JNIEnv* env, const char* cmd) {
jstring jstr = (jstring)env->CallStaticObjectMethod(gVintfObjectClazz, gRunCommand,
env->NewStringUTF(cmd));
std::string output;
if (jstr) {
auto cstr = env->GetStringUTFChars(jstr, nullptr);
output = std::string(cstr);
env->ReleaseStringUTFChars(jstr, cstr);
} else {
LOG(WARNING) << "Failed to run " << cmd;
env->ExceptionDescribe();
env->ExceptionClear();
}
return output;
}
template <typename T>
static std::shared_ptr<const T> fromXml(const std::string& content) {
std::shared_ptr<T> object = std::make_unique<T>();
std::string error;
if (fromXml(object.get(), content, &error)) {
return object;
}
LOG(WARNING) << "Unabled to parse: " << error;
return nullptr;
}
static std::shared_ptr<const HalManifest> getDeviceHalManifest(JNIEnv* env) {
return fromXml<HalManifest>(runCmd(env, "vintf dm"));
}
static std::shared_ptr<const HalManifest> getFrameworkHalManifest(JNIEnv* env) {
return fromXml<HalManifest>(runCmd(env, "vintf fm"));
}
static std::shared_ptr<const CompatibilityMatrix> getDeviceCompatibilityMatrix(JNIEnv* env) {
return fromXml<CompatibilityMatrix>(runCmd(env, "vintf dcm"));
}
static std::shared_ptr<const CompatibilityMatrix> getFrameworkCompatibilityMatrix(JNIEnv* env) {
return fromXml<CompatibilityMatrix>(runCmd(env, "vintf fcm"));
}
template<typename V>
static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) {
size_t i;
......@@ -83,12 +135,10 @@ static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass)
{
std::vector<std::string> cStrings;
tryAddSchema(VintfObject::GetDeviceHalManifest(), "device manifest", &cStrings);
tryAddSchema(VintfObject::GetFrameworkHalManifest(), "framework manifest", &cStrings);
tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), "device compatibility matrix",
&cStrings);
tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), "framework compatibility matrix",
&cStrings);
tryAddSchema(getDeviceHalManifest(env), "device manifest", &cStrings);
tryAddSchema(getFrameworkHalManifest(env), "framework manifest", &cStrings);
tryAddSchema(getDeviceCompatibilityMatrix(env), "device compatibility matrix", &cStrings);
tryAddSchema(getFrameworkCompatibilityMatrix(env), "framework compatibility matrix", &cStrings);
return toJavaStringArray(env, cStrings);
}
......@@ -108,15 +158,13 @@ static jint android_os_VintfObject_verifyBuildAtBoot(JNIEnv*, jclass) {
static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
std::set<std::string> halNames;
tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(),
"device manifest", &halNames);
tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(),
"framework manifest", &halNames);
tryAddHalNamesAndVersions(getDeviceHalManifest(env), "device manifest", &halNames);
tryAddHalNamesAndVersions(getFrameworkHalManifest(env), "framework manifest", &halNames);
return toJavaStringArray(env, halNames);
}
static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) {
LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest";
return nullptr;
......@@ -126,8 +174,7 @@ static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
}
static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jclass) {
std::shared_ptr<const CompatibilityMatrix> matrix =
VintfObject::GetFrameworkCompatibilityMatrix();
std::shared_ptr<const CompatibilityMatrix> matrix = getFrameworkCompatibilityMatrix(env);
if (matrix == nullptr || matrix->type() != SchemaType::FRAMEWORK) {
jniThrowRuntimeException(env, "Cannot get framework compatibility matrix");
return nullptr;
......@@ -148,7 +195,7 @@ static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jc
}
static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
std::shared_ptr<const HalManifest> manifest = getFrameworkHalManifest(env);
if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest";
return nullptr;
......@@ -163,7 +210,7 @@ static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
}
static jobject android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion(JNIEnv* env, jclass) {
std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
if (manifest == nullptr || manifest->level() == Level::UNSPECIFIED) {
return nullptr;
}
......@@ -188,19 +235,20 @@ static const JNINativeMethod gVintfObjectMethods[] = {
const char* const kVintfObjectPathName = "android/os/VintfObject";
int register_android_os_VintfObject(JNIEnv* env)
{
int register_android_os_VintfObject(JNIEnv* env) {
gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap"));
gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V");
gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz,
"put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, "put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
gLongClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Long"));
gLongValueOf = GetStaticMethodIDOrDie(env, gLongClazz, "valueOf", "(J)Ljava/lang/Long;");
gVintfObjectClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, kVintfObjectPathName));
gRunCommand = GetStaticMethodIDOrDie(env, gVintfObjectClazz, "runShellCommand",
"(Ljava/lang/String;)Ljava/lang/String;");
return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
NELEM(gVintfObjectMethods));
NELEM(gVintfObjectMethods));
}
extern int register_android_os_VintfRuntimeInfo(JNIEnv* env);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment