Codebase list xdg-desktop-portal / 65a55ae
screencast: Don't cast remote desktop sessions to screencast The replace_restore_token_with_data() function is called both for remote desktop and screencast sessions. However, it was always casting and using to ScreenCastSession, even when a remote desktop session was passed. This could lead to memory corruption. Be more careful when casting the Session object to ScreenCastSession. Move the casting entirely to inside replace_restore_token_with_data(), and make sure the only code paths that perform type casting are safely guarded by either is_remote_desktop_session or is_screen_cast_session checks. This is a regression from the screencast restore PR. Closes https://github.com/flatpak/xdg-desktop-portal/issues/771 Georges Basile Stavracas Neto authored 2 years ago Phaedrus Leeds committed 2 years ago
1 changed file(s) with 16 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
576576 };
577577
578578 static gboolean
579 replace_restore_token_with_data (ScreenCastSession *screen_cast_session,
579 replace_restore_token_with_data (Session *session,
580580 GVariant **in_out_options,
581581 GError **error)
582582 {
583 Session *session = (Session *)screen_cast_session;
584583 GVariantBuilder options_builder;
585584 g_autoptr(GVariant) options = NULL;
585 PersistMode persist_mode;
586586 gsize i;
587587
588588 options = *in_out_options;
589589
590 if (!g_variant_lookup (options, "persist_mode", "u", &screen_cast_session->persist_mode))
591 screen_cast_session->persist_mode = PERSIST_MODE_NONE;
592
593 if (is_remote_desktop_session (session) && screen_cast_session->persist_mode != PERSIST_MODE_NONE)
590 if (!g_variant_lookup (options, "persist_mode", "u", &persist_mode))
591 persist_mode = PERSIST_MODE_NONE;
592
593 if (is_remote_desktop_session (session) && persist_mode != PERSIST_MODE_NONE)
594594 {
595595 g_set_error (error, XDG_DESKTOP_PORTAL_ERROR, XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
596596 "Remote desktop sessions cannot persist");
597597 return FALSE;
598598 }
599599
600 if (is_screen_cast_session (session))
601 {
602 ScreenCastSession *screen_cast_session = (ScreenCastSession *)session;
603 screen_cast_session->persist_mode = persist_mode;
604 }
605
600606 g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
601607 for (i = 0; i < G_N_ELEMENTS (screen_cast_select_sources_options); i++)
602608 {
611617
612618 if (g_strcmp0 (screen_cast_select_sources_options[i].key, "restore_token") == 0)
613619 {
620 ScreenCastSession *screen_cast_session;
614621 g_autoptr(GVariant) restore_data = NULL;
615622 g_autofree char *restore_token = NULL;
616623
655662 * apps can pass random UUIDs and yet predict what the next token will
656663 * be.
657664 */
665 g_assert (is_screen_cast_session (session));
666 screen_cast_session = (ScreenCastSession *)session;
658667 screen_cast_session->restore_token = g_steal_pointer (&restore_token);
659668
660669 g_debug ("Replacing 'restore_token' with portal-specific data");
681690 {
682691 Request *request = request_from_invocation (invocation);
683692 Session *session;
684 ScreenCastSession *screen_cast_session;
685693 g_autoptr(GError) error = NULL;
686694 g_autoptr(XdpDbusImplRequest) impl_request = NULL;
687695 GVariantBuilder options_builder;
785793 * permission store and / or the GHashTable with transient permissions.
786794 * Portal implementations do not have access to the restore token.
787795 */
788 screen_cast_session = (ScreenCastSession *) session;
789 if (!replace_restore_token_with_data (screen_cast_session, &options, &error))
796 if (!replace_restore_token_with_data (session, &options, &error))
790797 {
791798 g_dbus_method_invocation_return_gerror (invocation, error);
792799 return G_DBUS_METHOD_INVOCATION_HANDLED;