From 14744f64568d1875f1680b720f3c62d2488ec242 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Mon, 7 Oct 2019 11:08:32 +0200 Subject: [PATCH] doc: overview, purpose, design, implementation The description of the libdbuspolicy project. It includes the overview, the purpose, the description of the design and the implementation, and additionally notes for improvements made or considered. Change-Id: I6b0bc9028ed86cb688d0dac9e910c10d3c4d8bc5 (cherry picked from commit 92c61f4ae8c64d2be5adf809c1ba10a1cdb5e905) --- doc/documentation.rst | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 doc/documentation.rst diff --git a/doc/documentation.rst b/doc/documentation.rst new file mode 100644 index 0000000..00b4ade --- /dev/null +++ b/doc/documentation.rst @@ -0,0 +1,114 @@ +Libdbuspolicy documentation +--------------------------- + +This document describes purpose, assumptions, and implementation of libdbuspolicy. + +Doxygen docs +------------ + +API and many internal functions and methods are described in doxygen markups through the code. +This document does not describe API or any particular function or method. + +Purpose +------- + +Tizen on some platforms supports kdbus, an in-kernel D-Bus implementation. Kdbus systems +work without central D-Bus daemon (dbus-daemon) running. Messages are passed between +processes by the kernel driver. The driver supports some kind of access control, +but it is not sufficient for Tizen. For example, it does not support Cynara privileges. + +That's why this library has been created. It controls accesses and sits between +D-Bus libraries and the kdbus driver. D-Bus libraries, which support libdbuspolicy +are libdbus and glib. systemd's sd-bus does not support libdbuspolicy. Libdbuspolicy +uses standard XML policy files as defined for dbus-daemon. + +Security considerations +----------------------- + +If a rogue program is executed, it can bypass libdbus, glib and libdbuspolicy +and connect directly to kdbus to send or receive messages. Only file access rules apply. +However, if other clients use standard libdbus or glib libraries, the messages +will be checked against both sending and receiving policy. The only real +downside is owning policy. A rogue program can own any name, and even hijack names +from other owners. + +Implementation (a bit of history) +------------------------------------- + +Implementation of libdbuspolicy went through several phases. In the first phase +a database of rules was created. The database was in fact two databases: system and session +database. Each of them was divided into default, mandatory, user and group sub-databases. + +This basic structure was maintained at least until 2019. + +In 2018 it appeared that memory consumption of the database was too big. Heavy kilobytes +multiplied by over a hundred of processes were taking up heavy megabytes. Additionally, +initialization of the database slowed down each program which was using D-Bus. This led +to code refactoring and introducing serialization. + +Google's FlatBuffers (https://google.github.io/flatbuffers/) were selected to implement +serialization. In order to do that, the code was heavily refactored. + +Layers +------ + +There are the following layers in libdbuspolicy: + +#. API and programs: library code for connecting database searches with acquiring data from kdbus, + and program code for the utilities, i.e. printer, serializer, finder; +#. checking: library code for handling access check requests, with full information; it performs + several database queries per one check; +#. database: data keeping, searching and converting; +#. FlatBuffers: serialization and deserialization. + +There is also some helping code for printing diagnostics, etc. + +Design +------ + +The almost current overview of the design of the checking, database, and FlatBuffers layers: + +.. image:: dia/Classes-use-only-serialized.png + +Diagram description: + +#. MatchItem, MatchItemWithUserAndGroup - queries constructed by PolicyChecker; +#. PolicyChecker - entry point for checking policy; creates MatchItems to pass them + to StorageBackendSerialized; +#. StorageBackend - interface class; defines query interface for PolicyChecker, + and provides entry point for printing content; +#. StorageBackendXML - storage specific for XML-based data; supports adding items and + provides accessory functions for serialization; serves as an intermediate stage + for StorageBackendSerialized; +#. XmlParser - parser for XML data; creates items and adds them to StorageBackendXML; +#. StorageBackendSerialized - storage specific for serialized data; +#. Serializer - a translator between XML-based data and serialized data; used as an + entry point for serializator tool; used for creating serialized data from + StorageBackendXML; +#. Printer - an entry point for printer tool; +#. FlatBuffers - a library used for management of serialized data. + +The implementation differs from the design mostly in these ways: + +#. StorageBackendXML no longer is able to get decisions (getDecisionItem*), it is used + only for conversion to serialized form (StorageBackendSerialized) +#. Additional use case, Finder, was added; it's a bit like 'grep' for policies: prints + matching rules for a given query + +Improvements +------------ + +Instead of a direct linear search a simple mapping index for send rules was introduced +in StorageBackendSerialized. Basically, it creates a map for send_destination names. +Send_destination is a parameter by which the rules differ the most. Thus, "splitting" +linear search over just matching send_destination names gives significant performance +boost. As of Oct 2019 it has been implemented without the serialization. It needs +about 15KB per process. Therefore, there is a plan to add the serialization to the index. + +Additionally, there is a concept of creating a direct acycling graph containing the rules. +It would contains "levels", for keeping track of various parts of the query/key +(name, interface, method, object, message type, etc.). Each level is dedicated for +one part. A node in a level in which key is a text can be e.g. a trie. A query would +traverse the dag through levels, until reaching a leaf with ALLOW, DENY or CHECK value. +Creating and serializing such graph would make the querying process very fast and low-memory +consuming. -- 2.7.4