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

Commit 597f6376 authored by Connor O'Brien's avatar Connor O'Brien
Browse files

libtimeinstate: check for invalid buckets when reading map



The indexing logic in getUidsUpdatedConcurrentTimes relies on the keys
read from the BPF map being valid and assumes that the maximum bucket
number is determined by the number of CPUs. Add a check to fail
immediately if an invalid, higher bucket is encountered.
Also add a new test in libtimeinstate_test to check this case.

Test: added test case passes only if the check is present.
Bug: 166696502
Signed-off-by: default avatarConnor O'Brien <connoro@google.com>
Change-Id: I129a3b6491c869124dbbf5c694f82def9d5a8c98
parent fe3c19fc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -425,6 +425,7 @@ std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsUpdatedCon

    uint64_t newLastUpdate = lastUpdate ? *lastUpdate : 0;
    do {
        if (key.bucket > (gNCpus - 1) / CPUS_PER_ENTRY) return {};
        if (lastUpdate) {
            auto uidUpdated = uidUpdatedSince(key.uid, *lastUpdate, &newLastUpdate);
            if (!uidUpdated.has_value()) return {};
+22 −0
Original line number Diff line number Diff line
@@ -387,6 +387,28 @@ TEST(TimeInStateTest, AllUidConcurrentTimesSanityCheck) {
    }
}

TEST(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) {
    uint32_t uid = 0;
    {
        // Find an unused UID
        auto map = getUidsConcurrentTimes();
        ASSERT_TRUE(map.has_value());
        ASSERT_FALSE(map->empty());
        for (const auto &kv : *map) uid = std::max(uid, kv.first);
        ++uid;
    }
    android::base::unique_fd fd{
        bpf_obj_get(BPF_FS_PATH "map_time_in_state_uid_concurrent_times_map")};
    ASSERT_GE(fd, 0);
    uint32_t nCpus = get_nprocs_conf();
    uint32_t maxBucket = (nCpus - 1) / CPUS_PER_ENTRY;
    time_key_t key = {.uid = uid, .bucket = maxBucket + 1};
    std::vector<concurrent_val_t> vals(nCpus);
    ASSERT_FALSE(writeToMapEntry(fd, &key, vals.data(), BPF_NOEXIST));
    EXPECT_FALSE(getUidsConcurrentTimes().has_value());
    ASSERT_FALSE(deleteMapEntry(fd, &key));
}

TEST(TimeInStateTest, AllUidTimesConsistent) {
    auto tisMap = getUidsCpuFreqTimes();
    ASSERT_TRUE(tisMap.has_value());