Skip to content

Commit

Permalink
camera: fix permission check in OpenPipeWireRemote
Browse files Browse the repository at this point in the history
6cd99b0 changed the logic that the
camera portal uses to look up permissions for the AccessCamera method.
Applications first call AccessCamera to ensure they have camera
permission and to prompt the user if permission is missing, then they
call OpenPipeWireRemote, which fails if permission is missing. The
permission lookup logic needs to be the same in both places. Currently
when running Snapshot launched by GNOME Shell (rather than launched in a
terminal), Snapshot passes AccessCamera's permission check, then fails
OpenPipeWireRemote's permission check, causing camera access to be
denied without allowing the user to grant permission.

Also, since the same commit the code uses the XdpAppInfo on a secondary
thread. I suspect this is unsafe, and the original code avoided doing
so; therefore, let's be careful and move this logic to the main thread
so that the secondary thread only receives a copy of the app ID, as
before.

https://gitlab.gnome.org/GNOME/snapshot/-/issues/267
  • Loading branch information
mcatanzaro authored and GeorgesStavracas committed Jan 16, 2025
1 parent 7928c83 commit 316b950
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions src/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ query_permission_sync (XdpRequest *request)
const char *app_id;
gboolean allowed;

if (xdp_app_info_is_host (request->app_info))
app_id = "";
else
app_id = (const char *)g_object_get_data (G_OBJECT (request), "app-id");

app_id = (const char *)g_object_get_data (G_OBJECT (request), "app-id");
permission = xdp_get_permission_sync (app_id, PERMISSION_TABLE, PERMISSION_DEVICE_CAMERA);
if (permission == XDP_PERMISSION_ASK || permission == XDP_PERMISSION_UNSET)
{
Expand Down Expand Up @@ -190,6 +186,16 @@ handle_access_camera_in_thread_func (GTask *task,
}
}

static const char *
app_id_from_app_info (XdpAppInfo *app_info)
{
/* Automatically grant camera access to unsandboxed apps. */
if (xdp_app_info_is_host (app_info))
return "";

return xdp_app_info_get_id (app_info);
}

static gboolean
handle_access_camera (XdpDbusCamera *object,
GDBusMethodInvocation *invocation,
Expand All @@ -211,9 +217,7 @@ handle_access_camera (XdpDbusCamera *object,

REQUEST_AUTOLOCK (request);

app_id = xdp_app_info_get_id (request->app_info);


app_id = app_id_from_app_info (request->app_info);
g_object_set_data_full (G_OBJECT (request), "app-id", g_strdup (app_id), g_free);

xdp_request_export (request, g_dbus_method_invocation_get_connection (invocation));
Expand Down Expand Up @@ -288,7 +292,7 @@ handle_open_pipewire_remote (XdpDbusCamera *object,
}

app_info = xdp_invocation_lookup_app_info_sync (invocation, NULL, &error);
app_id = xdp_app_info_get_id (app_info);
app_id = app_id_from_app_info (app_info);
permission = xdp_get_permission_sync (app_id, PERMISSION_TABLE, PERMISSION_DEVICE_CAMERA);
if (permission != XDP_PERMISSION_YES)
{
Expand Down

0 comments on commit 316b950

Please sign in to comment.