Block SHELL_UID from overlay fabricate and clear shell overlays on boot

Prevents non-root shell from fabricating overlays and removes all
overlays with their creating package as shell on boot.

Prevents unapproved usages of the fabrication API and cleans up
any potentially broken overlays respectively.

Bug: 202768292

Test: sts-tradefed run sts-engbuild-no-spl-lock \
        -m StsHostTestCases -t android.security.sts.Bug_202768292

Change-Id: I184cc498e49c416e184cc0855a8810b57dd08175
(cherry picked from commit 627d5eb68e19a8ea18c3c1405701b3a33f073315)
Merged-In:I184cc498e49c416e184cc0855a8810b57dd08175
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 27b1648..ee0b3d5 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -71,6 +71,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -81,7 +82,6 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
-
 import com.android.server.pm.UserManagerService;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 
@@ -285,6 +285,12 @@
 
             restoreSettings();
 
+            // Wipe all shell overlays on boot, to recover from a potentially broken device
+            String shellPkgName = TextUtils.emptyIfNull(
+                    getContext().getString(android.R.string.config_systemShell));
+            mSettings.removeIf(overlayInfo -> overlayInfo.isFabricated
+                    && shellPkgName.equals(overlayInfo.packageName));
+
             initIfNeeded();
             onSwitchUser(UserHandle.USER_SYSTEM);
 
@@ -891,6 +897,16 @@
                     throw new IllegalArgumentException(request.typeToString()
                             + " unsupported for user " + request.userId);
                 }
+
+                // Normal apps are blocked from accessing OMS via SELinux, so to block non-root,
+                // non privileged callers, a simple check against the shell UID is sufficient, since
+                // that's the only exception from the other categories. This is enough while OMS
+                // is not a public API, but this will have to be changed if it's ever exposed.
+                if (callingUid == Process.SHELL_UID) {
+                    EventLog.writeEvent(0x534e4554, "202768292", -1, "");
+                    throw new IllegalArgumentException("Non-root shell cannot fabricate overlays");
+                }
+
                 realUserId = UserHandle.USER_ALL;
 
                 // Enforce that the calling process can only register and unregister fabricated