ApkVerityTestApp: Check FS_VERITY_FL if kernel doesn't support STATX_ATTR_VERITY

(cherry picked from aosp/1836122)

Bug: 169376551
Bug: 199815666
Bug: 205516323
Test: atest ApkVerityInstallTest

Change-Id: Id8b2161384d1cf1ad75c26109f51edcc414dd879
diff --git a/hostsidetests/appsecurity/test-apps/ApkVerityTestApp/jni/android_appsecurity_cts_apkveritytestapp_InstalledFilesCheck.cpp b/hostsidetests/appsecurity/test-apps/ApkVerityTestApp/jni/android_appsecurity_cts_apkveritytestapp_InstalledFilesCheck.cpp
index abc04d9..89b832d 100644
--- a/hostsidetests/appsecurity/test-apps/ApkVerityTestApp/jni/android_appsecurity_cts_apkveritytestapp_InstalledFilesCheck.cpp
+++ b/hostsidetests/appsecurity/test-apps/ApkVerityTestApp/jni/android_appsecurity_cts_apkveritytestapp_InstalledFilesCheck.cpp
@@ -24,6 +24,8 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -35,17 +37,33 @@
     JNIEnv *env, jobject /*thiz*/, jstring filePath) {
   ScopedUtfChars path(env, filePath);
 
+  // Call statx and check STATX_ATTR_VERITY.
   struct statx out = {};
   if (statx(AT_FDCWD, path.c_str(), 0 /* flags */, STATX_ALL, &out) != 0) {
     ALOGE("statx failed at %s", path.c_str());
     return JNI_FALSE;
   }
 
-  // Sanity check.
-  if ((out.stx_attributes_mask & STATX_ATTR_VERITY) == 0) {
-    ALOGE("STATX_ATTR_VERITY not supported by kernel");
+  if (out.stx_attributes_mask & STATX_ATTR_VERITY) {
+    return (out.stx_attributes & STATX_ATTR_VERITY) != 0 ? JNI_TRUE : JNI_FALSE;
+  }
+
+  // STATX_ATTR_VERITY is not supported by kernel for the file path.
+  // In this case, call ioctl(FS_IOC_GETFLAGS) and check FS_VERITY_FL.
+  int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
+  if (fd < 0) {
+    ALOGE("failed to open %s", path.c_str());
     return JNI_FALSE;
   }
 
-  return (out.stx_attributes & STATX_ATTR_VERITY) != 0 ? JNI_TRUE : JNI_FALSE;
+  unsigned int flags;
+  int ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+  close(fd);
+
+  if (ret < 0) {
+    ALOGE("ioctl(FS_IOC_GETFLAGS) failed at %s", path.c_str());
+    return JNI_FALSE;
+  }
+
+  return (flags & FS_VERITY_FL) != 0 ? JNI_TRUE : JNI_FALSE;
 }