Skip to content

Commit ddcf87c

Browse files
committed
fw/popups/notifications/window: fix crash due to cross-app free
If a notification was received (KernelMain) while viewing a notification from the notifications app, a cross-app free would occur because the prv_do_notification_vibe() call gets the current item from the swap layer (allocated by app), UUID would not match, causing a swap layer reload and so a timeline_item_destroy, freeing app-heap memory. Fixes FIRM-1322 Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
1 parent 43e7367 commit ddcf87c

File tree

1 file changed

+27
-25
lines changed

1 file changed

+27
-25
lines changed

src/fw/popups/notifications/notification_window.c

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,48 +1389,50 @@ static void prv_do_notification_vibe(NotificationWindowData *data, Uuid *id) {
13891389
}
13901390

13911391
static void prv_handle_notification_added_common(Uuid *id, NotificationType type) {
1392+
NotificationWindowData *data = &s_notification_window_data;
1393+
13921394
if (!alerts_should_notify_for_type(prv_alert_type_for_notification_type(type))) {
13931395
return;
13941396
}
13951397

1398+
alerts_incoming_alert_analytics();
1399+
13961400
if (do_not_disturb_is_active() &&
13971401
alerts_preferences_dnd_get_show_notifications() == DndNotificationModeHide) {
1398-
alerts_incoming_alert_analytics();
13991402
return;
14001403
}
14011404

1402-
NotificationWindowData *data = &s_notification_window_data;
1403-
14041405
// will fail and return early if already init'ed.
14051406
prv_init_notification_window(true /*is_modal*/);
14061407

1407-
if (data->is_modal) {
1408-
WindowStack *window_stack = modal_manager_get_window_stack(NOTIFICATION_PRIORITY);
1409-
bool is_new = !window_stack_contains_window(window_stack, &data->window);
1410-
bool in_view = window_is_on_screen(&data->window);
1408+
if (!data->is_modal) {
1409+
return;
1410+
}
14111411

1412-
prv_notification_window_add_notification(id, type);
1412+
WindowStack *window_stack = modal_manager_get_window_stack(NOTIFICATION_PRIORITY);
1413+
bool is_new = !window_stack_contains_window(window_stack, &data->window);
1414+
bool in_view = window_is_on_screen(&data->window);
14131415

1414-
if (is_new) {
1415-
data->first_notif_loaded = false;
1416-
prv_show_peek_for_notification(data, id, true /* is_first_notification */);
1417-
modal_window_push(&data->window, NOTIFICATION_PRIORITY, true /* animated */);
1418-
} else if (in_view) {
1419-
// Only focus the new notification if it becomes the new front of the list.
1420-
// In DND mode notifications can get inserted into the middle of the list and we don't
1421-
// want to change focus in this use case
1422-
if (notifications_presented_list_current() != notifications_presented_list_first()) {
1423-
const bool should_animate = !do_not_disturb_is_active();
1424-
notification_window_focus_notification(id, should_animate);
1425-
} else {
1426-
// If we are inserting into the middle of this list, just reaload the swap layer so the
1427-
// number of notifications displayed is correct
1428-
prv_reload_swap_layer(data);
1429-
}
1416+
prv_notification_window_add_notification(id, type);
1417+
1418+
if (is_new) {
1419+
data->first_notif_loaded = false;
1420+
prv_show_peek_for_notification(data, id, true /* is_first_notification */);
1421+
modal_window_push(&data->window, NOTIFICATION_PRIORITY, true /* animated */);
1422+
} else if (in_view) {
1423+
// Only focus the new notification if it becomes the new front of the list.
1424+
// In DND mode notifications can get inserted into the middle of the list and we don't
1425+
// want to change focus in this use case
1426+
if (notifications_presented_list_current() != notifications_presented_list_first()) {
1427+
const bool should_animate = !do_not_disturb_is_active();
1428+
notification_window_focus_notification(id, should_animate);
1429+
} else {
1430+
// If we are inserting into the middle of this list, just reaload the swap layer so the
1431+
// number of notifications displayed is correct
1432+
prv_reload_swap_layer(data);
14301433
}
14311434
}
14321435

1433-
alerts_incoming_alert_analytics();
14341436
if (alerts_should_vibrate_for_type(prv_alert_type_for_notification_type(type))) {
14351437
// Check if we should delay the vibration until the animation completes
14361438
if (alerts_preferences_get_notification_vibe_delay() && data->peek_layer) {

0 commit comments

Comments
 (0)