BPF: timeInState: fix possible bad data accounting
The bpf_get_current_uid_gid helper returns a 64bit value or -EINVAL in
the error case. This patch handles the error case by skipping time
accounting. The error case should only occur if something bad happend in
the kernel and there is a problem with the task struct.
Bug: 355147109
Test: treehugger
Change-Id: I74a0c0b19ac06754815abad1d21c98c950878d6b
Signed-off-by: Neill Kapron <nkapron@google.com>
diff --git a/timeInState.c b/timeInState.c
index 7c09736..85dda97 100644
--- a/timeInState.c
+++ b/timeInState.c
@@ -21,6 +21,7 @@
#endif
#include <bpf_timeinstate.h>
+#include <errno.h>
DEFINE_BPF_MAP_GRW(total_time_in_state_map, PERCPU_ARRAY, uint32_t, uint64_t, MAX_FREQS_FOR_TOTAL,
AID_SYSTEM)
@@ -155,7 +156,16 @@
// freq_to_idx_map uses 1 as its minimum index so that *freq_idxp == 0 only when uninitialized
uint8_t freq_idx = *freq_idxp - 1;
- uint32_t uid = bpf_get_current_uid_gid();
+ // The bpf_get_current_uid_gid() helper function returns a u64 value, with the lower 32 bits
+ // containing the UID and the upper 32 bits containing the GID. Additionally, in rare cases,
+ // (usually something is very wrong with the kernel) the helper can return -EINVAL, in which
+ // case we should just return early.
+ unsigned long long uid_gid = bpf_get_current_uid_gid();
+ if (uid_gid == (unsigned long long)(-EINVAL)) return ALLOW;
+
+ // Mask out the uid part of the uid_gid value returned from the kernel.
+ uint32_t uid = uid_gid & 0xFFFFFFFF;
+
uint64_t delta = time - old_last;
// For UIDs in the SDK sandbox range, we account per-UID times twice, both to the corresponding