[vold] Check incremental paths before mounting

Vold was trusting system_server too much and allowed for pretty
much any path in mount()/bindMount() calls for incremental.
This CL adds validation to make sure it's only accessing own
directories. This includes enforcing no symlinks in the paths

Bug: 198657657
Bug: 216722132
Test: manual
Change-Id: I6035447f94ef44c4ae3294c3ae47de2d7210683a
Merged-In: I6035447f94ef44c4ae3294c3ae47de2d7210683a
diff --git a/VoldNativeServiceValidation.cpp b/VoldNativeServiceValidation.cpp
index ee1e65a..1d19141 100644
--- a/VoldNativeServiceValidation.cpp
+++ b/VoldNativeServiceValidation.cpp
@@ -105,4 +105,31 @@
     return Ok();
 }
 
+binder::Status CheckIncrementalPath(IncrementalPathKind kind, const std::string& path) {
+    if (auto status = CheckArgumentPath(path); !status.isOk()) {
+        return status;
+    }
+    if (kind == IncrementalPathKind::MountSource || kind == IncrementalPathKind::MountTarget ||
+        kind == IncrementalPathKind::Any) {
+        if (android::base::StartsWith(path, "/data/incremental/MT_")) {
+            if (kind != IncrementalPathKind::MountSource &&
+                (android::base::EndsWith(path, "/mount") || path.find("/mount/") != path.npos)) {
+                return Ok();
+            }
+            if (kind != IncrementalPathKind::MountTarget &&
+                (android::base::EndsWith(path, "/backing_store") ||
+                 path.find("/backing_store/") != path.npos)) {
+                return Ok();
+            }
+        }
+    }
+    if (kind == IncrementalPathKind::Bind || kind == IncrementalPathKind::Any) {
+        if (android::base::StartsWith(path, "/data/app/")) {
+            return Ok();
+        }
+    }
+    return Exception(binder::Status::EX_ILLEGAL_ARGUMENT,
+                     StringPrintf("Path '%s' is not allowed", path.c_str()));
+}
+
 }  // namespace android::vold