OSDN Git Service

Harden against invalid paths.
authorDan Sandler <dsandler@android.com>
Thu, 13 Dec 2018 20:32:13 +0000 (15:32 -0500)
committerDaniel Sandler <dsandler@android.com>
Wed, 2 Jan 2019 19:42:21 +0000 (19:42 +0000)
Don't write them, and also, catch runtime exceptions during
persist operations.

Bug: 120749813
Test: atest frameworks/base/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java
Change-Id: Ie478814abf5b44e48c8179bee79578e90f4fe3d4
(cherry picked from commit 2d8e3d17f6a2f38b83da6a1b05246dde4e77cb59)

services/core/java/com/android/server/slice/SliceClientPermissions.java
services/core/java/com/android/server/slice/SlicePermissionManager.java
services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java

index e461e0d..ab94a59 100644 (file)
@@ -282,9 +282,12 @@ public class SliceClientPermissions implements DirtyTracker, Persistable {
         public synchronized void writeTo(XmlSerializer out) throws IOException {
             final int N = mPaths.size();
             for (int i = 0; i < N; i++) {
-                out.startTag(NAMESPACE, TAG_PATH);
-                out.text(encodeSegments(mPaths.valueAt(i)));
-                out.endTag(NAMESPACE, TAG_PATH);
+                final String[] segments = mPaths.valueAt(i);
+                if (segments != null) {
+                    out.startTag(NAMESPACE, TAG_PATH);
+                    out.text(encodeSegments(segments));
+                    out.endTag(NAMESPACE, TAG_PATH);
+                }
             }
         }
 
index 780bc96..315d5e3 100644 (file)
@@ -315,7 +315,8 @@ public class SlicePermissionManager implements DirtyTracker {
         return new AtomicFile(new File(mSliceDir, fileName));
     }
 
-    private void handlePersist() {
+    @VisibleForTesting
+    void handlePersist() {
         synchronized (this) {
             for (Persistable persistable : mDirty) {
                 AtomicFile file = getFile(persistable.getFileName());
@@ -335,7 +336,7 @@ public class SlicePermissionManager implements DirtyTracker {
 
                     out.flush();
                     file.finishWrite(stream);
-                } catch (IOException | XmlPullParserException e) {
+                } catch (IOException | XmlPullParserException | RuntimeException e) {
                     Slog.w(TAG, "Failed to save access file, restoring backup", e);
                     file.failWrite(stream);
                 }
@@ -344,6 +345,12 @@ public class SlicePermissionManager implements DirtyTracker {
         }
     }
 
+    // use addPersistableDirty(); this is just for tests
+    @VisibleForTesting
+    void addDirtyImmediate(Persistable obj) {
+        mDirty.add(obj);
+    }
+
     private void handleRemove(PkgUser pkgUser) {
         getFile(SliceClientPermissions.getFileName(pkgUser)).delete();
         getFile(SliceProviderPermissions.getFileName(pkgUser)).delete();
index dc057d5..b315e51 100644 (file)
@@ -101,4 +101,34 @@ public class SlicePermissionManagerTest extends UiServiceTestCase {
         assertTrue(FileUtils.deleteContentsAndDir(sliceDir));
     }
 
-}
\ No newline at end of file
+    @Test
+    public void testInvalid() throws Exception {
+        File sliceDir = new File(mContext.getCacheDir(), "slices-test");
+        if (!sliceDir.exists()) {
+            sliceDir.mkdir();
+        }
+        SlicePermissionManager permissions = new SlicePermissionManager(mContext,
+                TestableLooper.get(this).getLooper(), sliceDir);
+
+        DirtyTracker.Persistable junk = new DirtyTracker.Persistable() {
+            @Override
+            public String getFileName() {
+                return "invalidData";
+            }
+
+            @Override
+            public void writeTo(XmlSerializer out) throws IOException {
+                throw new RuntimeException("this doesn't work");
+            }
+        };
+
+        // let's put something bad in here
+        permissions.addDirtyImmediate(junk);
+        // force a persist. if this throws, it would take down system_server
+        permissions.handlePersist();
+
+        // Cleanup.
+        assertTrue(FileUtils.deleteContentsAndDir(sliceDir));
+    }
+
+}