Bugzilla – Bug 1216277
VUL-1: pdnsd: unsafe creation of /var/cache/pdnsd/pdnsd.cache via /usr/bin/install in service file
Last modified: 2024-04-19 10:05:22 UTC
In a recent pdns update in Factory the following systemd service content changed: RPM: pdnsd-1.2.9a-10.10.x86_64.rpm on x86_64 Package: pdnsd Service path: /usr/lib/systemd/system/pdnsd.service Runs as: root:root Exec lines: ExecStartPre=/usr/bin/install -m0644 -o pdns -g pdns /dev/null /var/cache/pdnsd/pdnsd.cache ExecStart=/usr/sbin/pdnsd $PDNSD_ARGS Changes with regard to previous service file: --- old.service +++ new.service @@ -3,4 +3,5 @@ Service path: /usr/lib/systemd/system/pdnsd.service Runs as: root:root Exec lines: - ExecStart=/usr/sbin/pdnsd + ExecStartPre=/usr/bin/install -m0644 -o pdns -g pdns /dev/null /var/cache/pdnsd/pdnsd.cache + ExecStart=/usr/sbin/pdnsd $PDNSD_ARGS This new `ExecStartPre=` line is problematic, since /var/cache/pdnsd is owned by pdns:pdns: $ ls -lhd /var/cache/pdnsd drwxr-x--- 3 pdns pdns 4.0K Oct 16 12:31 /var/cache/pdnsd Thus the directory is controlled by the `pdns` user. The `install` program performs the following system calls on the path. openat(AT_FDCWD, "/var/cache/pdnsd/pdnsd.cache", O_RDONLY|O_PATH|O_DIRECTORY) = -1 ENOTDIR (Not a directory) newfstatat(AT_FDCWD, "/var/cache/pdnsd/pdnsd.cache", {st_mode=S_IFLNK|0777, st_size=11, ...}, AT_SYMLINK_NOFOLLOW) = 0 unlinkat(AT_FDCWD, "/var/cache/pdnsd/pdnsd.cache", 0) = 0 openat(AT_FDCWD, "/var/cache/pdnsd/pdnsd.cache", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4 fchownat(AT_FDCWD, "/var/cache/pdnsd/pdnsd.cache", 449, 458, AT_SYMLINK_NOFOLLOW) = 0 fchmodat(AT_FDCWD, "/var/cache/pdnsd/pdnsd.cache", 0644) = 0 Of these calls the `fchmodat()` is still vulnerable to symlink attacks. Since the directory in question does not have a sticky bit set, there will also be no kernel level symlink protection. A compromised "pdns" user account can attempt to win a race condition, deleting the file and replacing it by a symlink after `fchownat()` happens but before `fchmodat()` happens. Then the mode of arbitrary files in the system can be changed to mode 0644. This seems to be an openSUSE specific packaging error, since the service file is checked into OBS. To fix this I suggest to add "User=pdns", "Group=pdns" and if necessary run `pdnsd` still as root by prefixing a "!" (see `man systemd.service`).
I assigned this to the user that introduced the change. pdns as a package does not seem to have a maintainer assigned currently.
Kindly tell me when I did change this because I am not aware of this change. Especially not in the near past.
(In reply to chris@computersalat.de from comment #2) > Kindly tell me when I did change this because I am not aware of this change. > Especially not in the near past. It seems the change is already a year old but has only now made it actually into Factory. It is this change entry from openSUSE:Factory/pdnsd: > ------------------------------------------------------------------- > Thu Sep 15 14:54:23 UTC 2022 - chris@computersalat.de > > - rework patches to be p0 > - add pdnsd_conf.patch > * mainly just beautification for better readability > - add pdnsd.sysconfig file > * ability to pass ARGS > - service files > * update pdnsd.service > * add pdnsd.service.sle12 > - add user/group pdns
(In reply to Christian Wittmer from comment #2) > Kindly tell me when I did change this because I am not aware of this change. > Especially not in the near past. It seems you've cut yourself off from further bug updates by assigning the bug to me. Please find the answer to your question in comment 3.
OK, I think I get it. I do remember this workaround for making pdnsd start even when there is no cache file. IMHO sadly the cache file is not created by the daemon on start. If there is no cache file then the daemon fails to start. Do you have a better idea to create a cache file ? So it does exist on service start ?
problem fixed with a systemd tmpfile. OBS SR created: https://build.opensuse.org/request/show/1122870
Please don't close VUL- bugs on your own. The security team will do it. The systemd-tmpfiles approach should fix this. You can also try to approach upstream about this behaviour and ask them to make the daemon behaviour more robust. Sadly we don't have a dedicated pdns anymore so no one is properly taking care of it.
(In reply to Matthias Gerstner from comment #8) > Please don't close VUL- bugs on your own. The security team will do it. > > The systemd-tmpfiles approach should fix this. > > You can also try to approach upstream about this behaviour and ask them to > make the daemon behaviour more robust. > > Sadly we don't have a dedicated pdns anymore so no one is properly taking > care > of it. sorry, won't do it again. IMHO there is no upstream anymore ... looks orphaned/dead I also don't know if it is really being used actively ...
If wanted, I can take ownership of this package as I am using/maintaining a derivative of it in a commercial setting anyway. I would rework the packaging quite a bit probably, though ;-)
(In reply to seife@novell.slipkontur.de from comment #10) > If wanted, I can take ownership of this package as I am using/maintaining a derivative of it in a commercial setting anyway. > > I would rework the packaging quite a bit probably, though ;-) If you feel up to the task then we would be happy of course. Otherwise, since upstream is also not active anymore, we might need to drop.
(In reply to Stefan Seyfried from comment #10) > If wanted, I can take ownership of this package as I am using/maintaining a > derivative of it in a commercial setting anyway. > > I would rework the packaging quite a bit probably, though ;-) Please go ahead
I requested maintainership in request 1123676. (Even though I technically could just add myself as I am one of the network project maintainers for historical reasons, I don't like such overstepping of processes and self-elevation ;-) The fix for this issue is on its way to factory as request 1123675
Christian, for me pdnsd starts just fine without this cache file present. It only issues a warning once: (I have removed the ExecStartPre line from the old in-factory version of the package). strolchi:~ # rm /var/cache/pdnsd/pdnsd.cache strolchi:~ # systemctl start pdnsd.service strolchi:~ # pdnsd-ctl server 0 up Opening socket /var/cache/pdnsd/pdnsd.status Succeeded strolchi:~ # nslookup heise.de 127.1 Server: 127.1 Address: 127.0.0.1#53 Non-authoritative answer: Name: heise.de Address: 193.99.144.80 Name: heise.de Address: 2a02:2e0:3fe:1001:302:: strolchi:~ # systemctl stop pdnsd.service strolchi:~ # ls -l /var/cache/pdnsd/pdnsd.cache -rw------- 1 pdns pdns 91 Nov 7 18:39 /var/cache/pdnsd/pdnsd.cache strolchi:~ # systemctl status pdnsd.service ○ pdnsd.service - Caching DNS proxy (pdns) Loaded: loaded (/usr/lib/systemd/system/pdnsd.service; disabled; preset: disabled) Active: inactive (dead) Docs: man:pdnsd(8) Nov 07 18:38:21 strolchi systemd[1]: Stopping Caching DNS proxy (pdns)... Nov 07 18:38:21 strolchi systemd[1]: pdnsd.service: Deactivated successfully. Nov 07 18:38:21 strolchi systemd[1]: Stopped Caching DNS proxy (pdns). Nov 07 18:39:01 strolchi systemd[1]: Started Caching DNS proxy (pdns). Nov 07 18:39:01 strolchi pdnsd[18037]: * 11/07 18:39:01| pdnsd: info: pdnsd-1.2.9a-par starting. Nov 07 18:39:01 strolchi pdnsd[18037]: * 11/07 18:39:01| pdnsd: warning: Could not open disk cache file /var/cache/pdnsd/pdnsd.cache:> Nov 07 18:39:29 strolchi pdnsd[18037]: * 11/07 18:39:29| pdnsd: warning: Caught signal 15. Exiting. Nov 07 18:39:29 strolchi systemd[1]: Stopping Caching DNS proxy (pdns)... Nov 07 18:39:29 strolchi systemd[1]: pdnsd.service: Deactivated successfully. Nov 07 18:39:29 strolchi systemd[1]: Stopped Caching DNS proxy (pdns). So I think this whole "create the cache file upfront" thing is not needed at all, the message is just cosmetic and just appearing once.
Stefan, we had very often failed service start because of this in our test environment. So my fix was to give the daemon its cache file before start. At that time I wasn't aware of this tmpfiles thing of systemd so I used this ugly ExecStartPre. I never experienced pdnsd creating the cache file so I don't know if it is good to have a DNS caching service without cache file ... It is your package. You decide.
I'm obviously interested in a package which just works, so I was thinking about patching the daemon to just create the file instead of erroring out. Until I found that the deamon actually does not error out if the file is missing, it behaves the same as if it has read an empty cache file. The file is created on the (controlled) shutdown. Right now I don't see where pdnsd might fail if the file is not present, but I might be overlooking somehting. Let's go for this "deal": I'll remove the cache file creation thing from the package (after again thoroughly looking at the code for paths where this might cause failure) and if you see failures to start up apparently linked to the missing cache file, we investigate and fix them? I think these startup failure are caused by some other bug which just get papered over if the file is created in advance.
sr#1128893 to factory contains an update which should fix this vulnerability: * no longer create the cache file from pdnsd.service * do not ship a tmpfile config creating the cache
This is an autogenerated message for OBS integration: This bug (1216277) was mentioned in https://build.opensuse.org/request/show/1128893 Factory / pdnsd
Thanks for working on this. We will close the bug when we verified all updates are available.
Thanks. And Christian: if you are seeing issues with the pdnsd not starting up when the cache file is missing, please create a bug and let's try to debug this and fix the root cause. Reading the code I cannot see what would make this happen, but I might of course be overlooking something.