From 86726ad7a468d4a8cc78ab41f392eb257833faad Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 25 Aug 2021 18:03:07 +0200 Subject: libtracker-data: Ensure tracker:id/uri can only look up allowed graphs Check with the per-graph Refcount table whether the ROWID involved is used in any allowed graph. Return 0/null otherwise. --- src/libtracker-data/tracker-sparql.c | 45 +++++++++++++++++++++++++++++++++--- tests/functional-tests/portal.py | 20 ++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c index 3d8c76b89..b562bd97d 100644 --- a/src/libtracker-data/tracker-sparql.c +++ b/src/libtracker-data/tracker-sparql.c @@ -82,6 +82,8 @@ static void _append_graph_checks (TrackerSparql *sparql, GStrv graphs, gint len); +static GHashTable * tracker_sparql_get_effective_graphs (TrackerSparql *sparql); + #define _raise(v,s,sub) \ G_STMT_START { \ g_set_error (error, TRACKER_SPARQL_ERROR, \ @@ -486,6 +488,28 @@ _escape_sql_string (const gchar *str, return copy; } +static inline void +_append_resource_rowid_access_check (TrackerSparql *sparql) +{ + GHashTable *graphs; + GList *names, *l; + + graphs = tracker_sparql_get_effective_graphs (sparql); + names = g_hash_table_get_keys (graphs); + + _append_string (sparql, "SELECT ID FROM Graph "); + + if (!sparql->policy.filter_unnamed_graph) + names = g_list_prepend (names, "main"); + + for (l = names; l; l = l->next) { + _append_string_printf (sparql, "UNION SELECT ID FROM \"%s\".Refcount ", + l->data); + } + + g_list_free (names); +} + static inline void _append_literal_sql (TrackerSparql *sparql, TrackerLiteralBinding *binding) @@ -545,8 +569,16 @@ _append_literal_sql (TrackerSparql *sparql, _append_string_printf (sparql, "?%d ", idx + 1); } - if (TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_RESOURCE) + if (TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_RESOURCE) { + if (sparql->policy.graphs || sparql->policy.filter_unnamed_graph) { + _append_string_printf (sparql, "AND ID IN ("); + _append_resource_rowid_access_check (sparql); + _append_string (sparql, ") "); + } + _append_string_printf (sparql, "), 0) "); + } + if (TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_STRING || TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_LANGSTRING) _append_string (sparql, "COLLATE " TRACKER_COLLATION_NAME " "); @@ -2160,8 +2192,15 @@ convert_expression_to_string (TrackerSparql *sparql, break; case TRACKER_PROPERTY_TYPE_RESOURCE: /* ID (or string) => Uri */ - _prepend_string (sparql, "SparqlPrintIRI("); - _append_string (sparql, ") "); + if (sparql->policy.graphs || sparql->policy.filter_unnamed_graph) { + _prepend_string (sparql, "SparqlPrintIRI((SELECT "); + _append_string (sparql, "AS ID WHERE ID IN ("); + _append_resource_rowid_access_check (sparql); + _append_string (sparql, "))) "); + } else { + _prepend_string (sparql, "SparqlPrintIRI("); + _append_string (sparql, ") "); + } break; case TRACKER_PROPERTY_TYPE_BOOLEAN: _prepend_string (sparql, "CASE "); diff --git a/tests/functional-tests/portal.py b/tests/functional-tests/portal.py index 2dbbd66c8..373bf8d5b 100644 --- a/tests/functional-tests/portal.py +++ b/tests/functional-tests/portal.py @@ -121,5 +121,25 @@ class TestPortal(fixtures.TrackerPortalTest): self.assertEqual(len(res), 1) self.assertEqual(res[0][0], 'b') + def test_06_id_access(self): + self.start_service('org.freedesktop.PortalTest') + self.update( + 'org.freedesktop.PortalTest', + 'CREATE GRAPH tracker:Allowed;' + + 'INSERT { GRAPH tracker:Allowed { a nfo:FileDataObject } }') + res = self.query( + 'org.freedesktop.PortalTest', + 'select tracker:id(xsd:string) tracker:uri(1) { }') + self.assertEqual(len(res), 1) + self.assertEqual(res[0][0], '0') + self.assertEqual(res[0][1], None) + + res = self.query( + 'org.freedesktop.PortalTest', + 'select tracker:id() tracker:uri(tracker:id()) { }') + self.assertEqual(len(res), 1) + self.assertNotEqual(res[0][0], '0') + self.assertEqual(res[0][1], 'b') + if __name__ == '__main__': fixtures.tracker_test_main() -- cgit v1.2.1