From adf3bd7e025bd2bb9555e86428f0103716f1c326 Mon Sep 17 00:00:00 2001 From: mtk80963 Date: Mon, 31 Mar 2025 07:23:31 -0700 Subject: [PATCH] Fix for b/404408218 that was not merged in time for the AOSP read-only migration. Add validity checks on DataStore file Add process to perform validity checks on DataStore to avoid system_server crashes by corrupted DataStore file. Flag: EXEMPT bugfix Test: Manual (cherry picked from https://android-review.googlesource.com/q/commit:e7deb2a847a87ed79747ab7a736a62072f79cde1) Fix for b/404408218 that was not merged in time for the AOSP read-only migration. (cherry picked from https://android-review.googlesource.com/q/commit:cbae03b06b1be8b877ac5ef13632969b9564b29d) Merged-In: I13c6ccc8bb5c2c9b212273350374b22892c67adc Change-Id: I13c6ccc8bb5c2c9b212273350374b22892c67adc --- .../com/android/server/net/ct/DataStore.java | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/networksecurity/service/src/com/android/server/net/ct/DataStore.java b/networksecurity/service/src/com/android/server/net/ct/DataStore.java index 1f99efa8e4..bd17199cdb 100644 --- a/networksecurity/service/src/com/android/server/net/ct/DataStore.java +++ b/networksecurity/service/src/com/android/server/net/ct/DataStore.java @@ -25,12 +25,15 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Optional; import java.util.Properties; +import java.util.Set; /** Class to persist data needed by CT. */ class DataStore extends Properties { private static final String TAG = "CertificateTransparency"; + private static final long MAX_FILE_SIZE = 20 * 1024; // 20KB + private static final int MAX_KEY_SIZE = 50; private final File mPropertyFile; DataStore(File file) { @@ -42,17 +45,49 @@ class DataStore extends Properties { if (!mPropertyFile.exists()) { return; } + + if (!validatePropertyFile()) { + Log.e(TAG, "Invalid property file, not load it!"); + delete(); + return; + } + try (InputStream in = new FileInputStream(mPropertyFile)) { load(in); + if (!validateProperties()) { + Log.e(TAG, "Invalid property store, clear it!"); + delete(); + return; + } } catch (IOException | IllegalArgumentException e) { Log.e(TAG, "Error loading property store", e); delete(); } } + private boolean validateProperties() { + Set keys = stringPropertyNames(); + for (String key : keys) { + if (key.length() > MAX_KEY_SIZE) { + Log.e(TAG, "Unexpected Property: " + key); + return false; + } + } + return true; + } + + private boolean validatePropertyFile() { + if (mPropertyFile.length() > MAX_FILE_SIZE) { + Log.e(TAG, "Property file size exceeds " + MAX_FILE_SIZE + "!"); + return false; + } + return true; + } + void store() { - try (OutputStream out = new FileOutputStream(mPropertyFile)) { + try (FileOutputStream out = new FileOutputStream(mPropertyFile)) { store(out, ""); + out.getFD().sync(); } catch (IOException e) { Log.e(TAG, "Error storing property store", e); }