diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java @@ -115,9 +115,14 @@ public class WebApkServiceClient { } private static Handler createPermissionHandler(Callback permissionCallback) { + // The Messenger backed by this Handler is sent to an external app which can + // reply any number of times. Enforce single-shot to prevent the native + // callback pointer from being freed twice (UAF / double-free). + final boolean[] called = {false}; return new Handler( Looper.getMainLooper(), message -> { + if (called[0]) return true; + called[0] = true; @ContentSetting int settingValue = toContentSettingValue(