When I build and install Akonadi (branch release/20.04) on Kubuntu 20.04, server was not able to start, because AppArmor denied access to DBus. I am not expert on AppArmor, but with these modifications, Akonadi is able to run.
Details
- Reviewers
knauss - Commits
- R165:39cb8ec4faa3: AppArmor DBus rules for AkonadiServer
- build install Akonadi on distribution with AppArmor (for example Kubuntu 20.04)
- start akonadi without applied patch, it should fail
- with this patch, it should run properly
Diff Detail
- Repository
- R165 Akonadi
- Lint
Automatic diff as part of commit; lint not applicable. - Unit
Automatic diff as part of commit; unit tests not applicable.
This dbus feature was added with newer AppArmor versions - I havn't heard about it until today ;) But this makes totally sense that also DBus access it controlled.
apparmor/usr.bin.akonadiserver | ||
---|---|---|
21 | Why Akonadi needs access to interface=org.freedesktop.DBus? | |
31 | is this really necessary? | |
44 | Replace with /usr/share/mysql/* r as mysql should be able to access its complete data. | |
63 | [0-9]* can be replaced with @{pid} as it does not need to access other processes. | |
65 | is this really necessary? | |
66 | is this really necessary? |
apparmor/usr.bin.akonadiserver | ||
---|---|---|
21 | Probably introspection, or listening to service added/removed signals |
Thank you for comments, I will make two small changes.
apparmor/usr.bin.akonadiserver | ||
---|---|---|
21 | without this line, akonadiserver fails with [C] 363117 Akonadi::Server::AkonadiServer::init:174 - Unable to connect to dbus service: "An AppArmor policy prevents this sender from sending this message to this recipient; type=\"method_call\", sender=\":1.2248\" (uid=1000 pid=363117 comm=\"/usr/bin/akonadiserver \" label=\"/usr/bin/akonadiserver (enforce)\") interface=\"org.freedesktop.DBus\" member=\"RequestName\" error name=\"(unset)\" requested_reply=\"0\" destination=\"org.freedesktop.DBus\" (bus)" It seems that "send" operation is enough... So, I will remove "receive". | |
31 | It seems that yes. AppArmor kernel module is blocking drkonqi execution otherwise. from dmesg: [126899.769752] audit: type=1400 audit(1587542245.999:1317): apparmor="DENIED" operation="exec" profile="/usr/bin/akonadiserver" name="/usr/lib/x86_64-linux-gnu/libexec/drkonqi" pid=370105 comm="ItemRetrievalMa" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0 | |
44 | ok, changing to whole subtree: /usr/share/mysql/** r, | |
63 | It needs access to mysqld (-akonadi) process, not itself. See this line https://cgit.kde.org/akonadi.git/tree/src/server/storage/dbconfigmysql.cpp#n314 | |
65 | Seems that yes. Some child process (thread?) wants to access it. When this line is removed, I see this audit message in dmesg: [126899.758977] audit: type=1400 audit(1587542245.987:1316): apparmor="DENIED" operation="connect" profile="/usr/bin/akonadiserver" name="/run/user/1000/kdeinit5__0" pid=369882 comm="ItemRetrievalMa" requested_mask="wr" denied_mask="wr" fsuid=1000 ouid=1000 | |
66 | Similar to previous. When I remove this line, AppArmor block creation of this directory/file. dmesg: [127294.059394] audit: type=1400 audit(1587542640.298:1362): apparmor="DENIED" operation="mknod" profile="/usr/bin/akonadiserver" name="/run/user/1000/kcrash_370375" pid=370375 comm="ItemRetrievalMa" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 |
- removed "receive" operation for org.freedesktop.DBus
- change read access to whole mysql subtree /usr/share/mysql/** r
Wait you add mysql stuff to the akonadiserver, that is totally wrong! The problem is that the mysql-akonadi script is not triggering the correct profile. The workaround with mysql-akonadi script was added because mysql start shipping AppArmor and Kubuntu/Debian mainatiners at that time created this script to make sure to workaround the AppArmor of mysql. Because this was triggering issues for Debian unstable I set down and started to do a proper AppArmor profile for Akonadi and there I learnt, that the mysql-akonadi script is not needed at all.
So please add /user/bin/mysql-akonadi PUx -> mysqld_akonadi, to your profile to make sure, that this ends up in the correct AppArmor space and than reevaluate the needed changes.
And I strongly recommend to get rid of this script too.
see:
https://bugs.kde.org/show_bug.cgi?id=399346#c13
https://salsa.debian.org/qt-kde-team/kde/akonadi/-/commit/f8096655237e9b716d51c36213ecaae79b8108de
https://salsa.debian.org/qt-kde-team/kde/akonadi/-/commit/dfd61ab8158a6938a707bebab00650e518411921
apparmor/usr.bin.akonadiserver | ||
---|---|---|
44 | Ah wait, this is completly wrong here. Mysql stuff is only inside apparmor/mysqld_akonadi. |
And I strongly recommend to get rid of this script too.
I may try to do it later. But not in scope of this review ;-)
apparmor/usr.bin.akonadiserver | ||
---|---|---|
44 | I don't wrote it explicitly, but this read access is not required by mysqld server, but mysql client (library?). Dmesg without this line: audit: type=1400 audit(1587620441.071:186): apparmor="DENIED" operation="open" profile="/usr/bin/akonadiserver" name="/usr/share/mysql/charsets/Index.xml" pid=23027 comm="akonadiserver" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 from akonadi strace: [pid 23027] execve("/usr/bin/akonadiserver", ["/usr/bin/akonadiserver"], 0x7ffda6565e98 /* 71 vars */ <unfinished ...> [pid 23027] <... execve resumed> ) = 0 ... [pid 23027] stat("/usr/share/mysql/charsets/Index.xml", {st_mode=S_IFREG|0644, st_size=19495, ...}) = 0 [pid 23027] openat(AT_FDCWD, "/usr/share/mysql/charsets/Index.xml", O_RDONLY) = -1 EACCES But it is true, that rule should not be here when akonadi is build with postgresql support. Should I add move it to mysqld profile? |
Okay I want to verify on my system first. I may find time to do this next week.
I'm very sorry that it takes that long, but I really want to understand why a line is needed. And I also learn AppArmor ;)
apparmor/usr.bin.akonadiserver | ||
---|---|---|
44 | Still seems fishy to me. Because that means that qt somehow changed their way how to connect to mysql.
we can't move this, as this is in process. it is no new binary that we can move to a different namespace. |
Stop Akonadi and start it with AKONADI_DEBUG_WAIT=akonadiserver, which will start the Akonadi Server and send it SIGSTOP immediately
AKONADI_DEBUG_WAIT=akonadiserver akonadictl start
In another terminal, attach strace to the Akonadi server process:
strace -f -p $(pidof akonadiserver)
In the first terminal, send SIGCONT to Akonadi to resume it
kill -SIGCONT $(pidof akonadiserver)
Or you can just stop whole akonadi, kill akonadi_control and start strace -f /usr/bin/akonadi_control 2>&1 | tee strace.log
Thanks dvratil and lukaskaras for explaining me how to debug Akonadi - I haven't done it yet. Btw. is there documentation existing for this?
For my local kdepim 20.04 upgrade + mariadb 1:10.3.22-1 on Debian Sid. I need no modifications from the shipped ones to run my kdepim setup afterwards successfully ( and it is running for more than one day already :):
- kcrash and drkonqi - this only happens, if Akonadi crashes and it does not crash for me yet - fully accepted
- dbus interface, this is a new way to lockdown dbus usage - fully accepted
- kdeinit - @dvratil does Akonadi uses/needs kdeinit?
In the end we have those two modifications /usr/share/mysql/** and @{PROC}/[0-9]*/stat that I do not get, why it does not explode for me.
So I want to understand, why you need such stuff and I don't:
@lukaskaras:
- Do you use MariaDB or Mysql?
- Do you test a new installation or running an existing one?
Both are points that already made in the past big difference for AppArmor profile and may explain the difference.
@lukaskaras - I'm very sorry that I am such an nip-picker on this issue. I hope you understand, that AppArmor only gives us more security, if we only allow the needed stuff. I see that it is your second proposed patch on Phabricator - and than such a hard one, that keeps you busy for a long time - I hope I do not scared you off from this team because of my reaction. I hope you still will propose more patches, normally patches get merged without such a lot discussion. I really enjoy that others enable AppArmor and also proposing patches and also like the really detailed answers from your side.
Re documentation: It's partially documented here: https://techbase.kde.org/KDE_PIM/Akonadi/Development_Tools - strace is not documented as far as I can see
Re kdeinit: Akonadi does not use kdeinit at all
- kcrash and drkonqi - this only happens, if Akonadi crashes and it does not crash for me yet - fully accepted
You may try to abort akonadi server by command:
killall -s ABRT akonadiserver
it should trigger Dr Konqi for your akonadiserver process
In the end we have those two modifications /usr/share/mysql/** and @{PROC}/[0-9]*/stat that I do not get, why it does not explode for me.
So I want to understand, why you need such stuff and I don't:
@lukaskaras:
- Do you use MariaDB or Mysql?
I am using MySQL 8.0.20.
from /usr/share/mysql/charsets/README:
Index.xml The Index.xml file lists all of the available charset configurations, including collations. Each collation must have a unique number. The number is stored IN THE DATABASE TABLE FILES and must not be changed. The max-id attribute of the <charsets> element must be set to the largest collation number.
and from configuration I just found this path:
mysql> show variables like 'character_sets_dir'; +--------------------+----------------------------+ | Variable_name | Value | +--------------------+----------------------------+ | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------+----------------------------+ 1 row in set (0.00 sec)
It is possible that MariaDB store these files somewhere else...
- Do you test a new installation or running an existing one?
It is existing installation. For clean installation, I would need to seetup virtual system...
Both are points that already made in the past big difference for AppArmor profile and may explain the difference.
Understand. There is always possibility that I made some configuration change that I forgot.
@lukaskaras - I'm very sorry that I am such an nip-picker on this issue. I hope you understand, that AppArmor only gives us more security, if we only allow the needed stuff. I see that it is your second proposed patch on Phabricator - and than such a hard one, that keeps you busy for a long time - I hope I do not scared you off from this team because of my reaction. I hope you still will propose more patches, normally patches get merged without such a lot discussion. I really enjoy that others enable AppArmor and also proposing patches and also like the really detailed answers from your side.
No problem, I am patient :-) It is more frustrating when you spend few hours with patch and receive no reply at all... I am happy that akonadi project is alive and has active community...
thanks for this idea to break the Akonadi process. Okay I used this methods to test this on my system and I need these two lines added:
ptrace read peer=mysqld_akonadi, owner /{,var/}run/user/@{uid}/kcrash** rwk,
mysql> show variables like 'character_sets_dir'; +--------------------+----------------------------+ | Variable_name | Value | +--------------------+----------------------------+ | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------+----------------------------+ 1 row in set (0.00 sec)
Same for my system but do not need to add /usr/share/mysql/, strange. I also can verify that it is accessed by akonadiserver via strace. Maybe the default Apparmor rules differ for Ubuntu and Debian.
Okay I think adding /usr/share/mysql/ won't hurt as there is no private data inside.
Let's add this and we reevalute this later.