Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d171517a authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Improve stability of battery stats history unparceling

If the battery history file is corrupted, the unparceling
code may call `parcel.setDataPosition` with an invalid
argument. This leads to an irrecoverable native crash
and process kill.  To avoid such a situation, we will be
checking the argument for validity before calling setDataPosition

Bug: 337977337
Test: atest FrameworksCoreTests:PowerStatsTest
Change-Id: Id4f1d7c27973eb975c0e7f87dc79491dc1b73101
parent 5be651f1
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -473,9 +473,16 @@ public final class PowerStats {
        } finally {
            // Unconditionally skip to the end of the written data, even if the actual parcel
            // format is incompatible
            if (endPos > parcel.dataPosition()) {
                if (endPos >= parcel.dataSize()) {
                    throw new IndexOutOfBoundsException(
                            "PowerStats end position: " + endPos + " is outside the parcel bounds: "
                                    + parcel.dataSize());
                }
                parcel.setDataPosition(endPos);
            }
        }
    }

    /**
     * Formats the stats as a string suitable to be included in the Battery History dump.
+14 −0
Original line number Diff line number Diff line
@@ -168,6 +168,20 @@ public class PowerStatsTest {
        assertThat(end).isEqualTo("END");
    }

    @Test
    public void parceling_corruptParcel() {
        PowerStats stats = new PowerStats(mDescriptor);
        Parcel parcel = Parcel.obtain();
        stats.writeToParcel(parcel);

        Parcel newParcel = marshallAndUnmarshall(parcel);
        newParcel.writeInt(-42);        // Negative section length
        newParcel.setDataPosition(0);

        PowerStats newStats = PowerStats.readFromParcel(newParcel, mRegistry);
        assertThat(newStats).isNull();
    }

    private static Parcel marshallAndUnmarshall(Parcel parcel) {
        byte[] bytes = parcel.marshall();
        parcel.recycle();