Skip to content

Commit a7025fe

Browse files
mrdewittmibrunin
authored andcommitted
[Backport] CVE-2021-30512: Use after free in Notifications
Partial cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/2838205: Notifications: crash if improper action icons sent from renderer. Previously, the code only called DCHECK but as this data is from a renderer we should probably crash the browser. Bug: 1200019 Change-Id: If4d9d48c8e18a3ed9c8bb3a50b952591259e0db5 Commit-Queue: Justin DeWitt <[email protected]> Reviewed-by: Peter Beverloo <[email protected]> Cr-Commit-Position: refs/heads/master@{#875788} Reviewed-by: Allan Sandfeld Jensen <[email protected]>
1 parent b162034 commit a7025fe

File tree

2 files changed

+32
-32
lines changed

2 files changed

+32
-32
lines changed

chromium/content/browser/notifications/blink_notification_service_impl.cc

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const char kBadMessageImproperNotificationImage[] =
3939
"disabled.";
4040
const char kBadMessageInvalidNotificationTriggerTimestamp[] =
4141
"Received an invalid notification trigger timestamp.";
42+
const char kBadMessageInvalidNotificationActionButtons[] =
43+
"Received a notification with a number of action images that does not "
44+
"match the number of actions.";
4245

4346
// Returns the implementation of the PlatformNotificationService. May be NULL.
4447
PlatformNotificationService* GetNotificationService(
@@ -132,7 +135,8 @@ void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
132135
mojo::PendingRemote<blink::mojom::NonPersistentNotificationListener>
133136
event_listener_remote) {
134137
DCHECK_CURRENTLY_ON(BrowserThread::UI);
135-
if (!ValidateNotificationResources(notification_resources))
138+
if (!ValidateNotificationDataAndResources(platform_notification_data,
139+
notification_resources))
136140
return;
137141

138142
if (!GetNotificationService(browser_context_))
@@ -187,28 +191,31 @@ BlinkNotificationServiceImpl::CheckPermissionStatus() {
187191
origin_.GetURL());
188192
}
189193

190-
bool BlinkNotificationServiceImpl::ValidateNotificationResources(
194+
bool BlinkNotificationServiceImpl::ValidateNotificationDataAndResources(
195+
const blink::PlatformNotificationData& platform_notification_data,
191196
const blink::NotificationResources& notification_resources) {
192-
if (notification_resources.image.drawsNothing() ||
193-
base::FeatureList::IsEnabled(features::kNotificationContentImage))
194-
return true;
195-
receiver_.ReportBadMessage(kBadMessageImproperNotificationImage);
196-
// The above ReportBadMessage() closes |binding_| but does not trigger its
197-
// connection error handler, so we need to call the error handler explicitly
198-
// here to do some necessary work.
199-
OnConnectionError();
200-
return false;
201-
}
197+
if (platform_notification_data.actions.size() !=
198+
notification_resources.action_icons.size()) {
199+
receiver_.ReportBadMessage(kBadMessageInvalidNotificationActionButtons);
200+
OnConnectionError();
201+
return false;
202+
}
202203

203-
// Checks if this notification has a valid trigger.
204-
bool BlinkNotificationServiceImpl::ValidateNotificationData(
205-
const blink::PlatformNotificationData& notification_data) {
206-
if (!CheckNotificationTriggerRange(notification_data)) {
204+
if (!CheckNotificationTriggerRange(platform_notification_data)) {
207205
receiver_.ReportBadMessage(kBadMessageInvalidNotificationTriggerTimestamp);
208206
OnConnectionError();
209207
return false;
210208
}
211209

210+
if (!notification_resources.image.drawsNothing() &&
211+
!base::FeatureList::IsEnabled(features::kNotificationContentImage)) {
212+
receiver_.ReportBadMessage(kBadMessageImproperNotificationImage);
213+
// The above ReportBadMessage() closes |binding_| but does not trigger its
214+
// connection error handler, so we need to call the error handler explicitly
215+
// here to do some necessary work.
216+
OnConnectionError();
217+
return false;
218+
}
212219
return true;
213220
}
214221

@@ -218,10 +225,8 @@ void BlinkNotificationServiceImpl::DisplayPersistentNotification(
218225
const blink::NotificationResources& notification_resources,
219226
DisplayPersistentNotificationCallback callback) {
220227
DCHECK_CURRENTLY_ON(BrowserThread::UI);
221-
if (!ValidateNotificationResources(notification_resources))
222-
return;
223-
224-
if (!ValidateNotificationData(platform_notification_data))
228+
if (!ValidateNotificationDataAndResources(platform_notification_data,
229+
notification_resources))
225230
return;
226231

227232
if (!GetNotificationService(browser_context_)) {

chromium/content/browser/notifications/blink_notification_service_impl.h

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,15 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
7171
// Check the permission status for the current |origin_|.
7272
blink::mojom::PermissionStatus CheckPermissionStatus();
7373

74-
// Validate |notification_resources| received in a Mojo IPC message.
75-
// If the validation failed, we'd close the Mojo connection |binding_| and
76-
// destroy |this| by calling OnConnectionError() directly, then return false.
77-
// So, please do not touch |this| again after you got a false return value.
78-
bool ValidateNotificationResources(
74+
// Validate |notification_data| and |notification_resources| received in a
75+
// Mojo IPC message. If the validation failed, we'd close the Mojo connection
76+
// |binding_| and destroy |this| by calling OnConnectionError() directly, then
77+
// return false. So, please do not touch |this| again after you got a false
78+
// return value.
79+
bool ValidateNotificationDataAndResources(
80+
const blink::PlatformNotificationData& notification_data,
7981
const blink::NotificationResources& notification_resources);
8082

81-
// Validate |notification_data| received in a Mojo IPC message.
82-
// If the validation failed, we'd close the Mojo connection |binding_| and
83-
// destroy |this| by calling OnConnectionError() directly, then return false.
84-
// So, please do not touch |this| again after you got a false return value.
85-
bool ValidateNotificationData(
86-
const blink::PlatformNotificationData& notification_data);
87-
8883
void DidWriteNotificationData(DisplayPersistentNotificationCallback callback,
8984
bool success,
9085
const std::string& notification_id);

0 commit comments

Comments
 (0)