From c4cfd83ad4a14c7ad6dbf72300f737984a1bd532 Mon Sep 17 00:00:00 2001 From: markchien Date: Fri, 18 Feb 2022 12:48:02 +0800 Subject: [PATCH] Fix system_server crash while iterating CookieTagMap When uid is removed, NetworkStatsService will iterate CookieTagMap and delete the corresponded uid socketTag value. But not only NetworkStatsService would detete CookieTagMap entries. There are other threads may also delete CookieTagMap entries such as #unTagSocket in bpfHandler and desctroy socket listener in TrafficController. System server crash as NPE because the CookieTagMap entry it iterate just be removed by other threads at the same time. This is just a simple fix to prevent the crash. Will have follow up CL for formal fix. Bug: 220084230 Test: m Change-Id: I08cad87f537fb09499faf1ff5cfd443fcb8ce436 --- .../src/com/android/server/net/NetworkStatsService.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java index eeb56d05e7..b193623114 100644 --- a/service-t/src/com/android/server/net/NetworkStatsService.java +++ b/service-t/src/com/android/server/net/NetworkStatsService.java @@ -1875,7 +1875,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private void deleteKernelTagData(int uid) { try { mCookieTagMap.forEach((key, value) -> { - if (value.uid == uid) { + // If SkDestroyListener deletes the socket tag while this code is running, + // forEach will either restart iteration from the beginning or return null, + // depending on when the deletion happens. + // If it returns null, continue iteration to delete the data and in fact it would + // just iterate from first key because BpfMap#getNextKey would return first key + // if the current key is not exist. + if (value != null && value.uid == uid) { try { mCookieTagMap.deleteEntry(key); } catch (ErrnoException e) {