Bug report: syslog-ng requests too many capabilities
Hi List, I recently noticed something very strange: although I run syslog-ng as an unprivileged user (with -u log -g log), newly created logfiles were owned by root. syslog-ng shows up running as user log in ps, as expected. The culprit turned out to be linux capabilities. No problem I thought, I just add a "--caps 'CAP_NET_BIND_SERVICE=epi'" command line parameter (binding ports <1024 is the only capability I need). But then I was getting flooded by messages like this: syslog-ng[25657]: Error managing capability set, cap_set_proc returned an error; caps='= cap_net_bind_service+eip cap_fowner+e', error='Operation not permitted (1)' In my opinion, there are 2 bugs in syslog-ng: * if I tell a daemon to run as unprivileged user I do not expect it to write files as user root. What syslog-ng is doing basically is faking being an unprivileged user, while retaining capabilities which are equivalent to full root permissions. Syslog-ng should imho either run as root, with capabilities; OR as unprivileged user without capabilities (except those explicitly given in --caps) * syslog-ng drops to the capabilities it gets told in --caps, but later g_process_cap_modify() ignores what was specified. Some notes about my environment: - the OS is an Ubuntu remix. I'm recompiling syslog-ng 3.11.1 from Ubuntu Artful, with some changed configure flags (see below) - there are multiple syslog-ng instances running. One for the system itself (as root), and multiple other syslogs receiving incoming logs over udp/tcp (running as user log) My syslog-ng version: syslog-ng 3 (3.11.1) Installer-Version: 3.11.1 Revision: Compile-Date: Apr 10 2017 14:06:00 Module-Directory: /usr/lib/syslog-ng/3.11 Module-Path: /usr/lib/syslog-ng/3.11 Available-Modules: disk-buffer,afsocket,afprog,system-source,kvformat,cef,affile,date,cryptofuncs,basicfuncs,confgen,pseudofile,csvparser,afuser,syslogformat,dbparser,linux-kmsg-format Enable-Debug: off Enable-GProf: off Enable-Memtrace: off Enable-IPv6: on Enable-Spoof-Source: off Enable-TCP-Wrapper: off Enable-Linux-Caps: on Enable-Systemd: off Thanks, Dominik
Hi!
"Russenberger" == Russenberger Dominik <dominik.russenberger@terreactive.ch> writes:
Russenberger> Hi List, Russenberger> I recently noticed something very strange: although I run syslog-ng as Russenberger> an unprivileged user (with -u log -g log), newly created logfiles were Russenberger> owned by root. syslog-ng shows up running as user log in ps, as expected. Russenberger> In my opinion, there are 2 bugs in syslog-ng: Russenberger> * if I tell a daemon to run as unprivileged user I do not expect it to Russenberger> write files as user root. What syslog-ng is doing basically is faking Russenberger> being an unprivileged user, while retaining capabilities which are Russenberger> equivalent to full root permissions. Russenberger> Syslog-ng should imho either run as root, with capabilities; Russenberger> OR as unprivileged user without capabilities (except those Russenberger> explicitly given in --caps) Russenberger> * syslog-ng drops to the capabilities it gets told in --caps, Russenberger> but later g_process_cap_modify() ignores what was specified. While I agree about your conclusion that syslog-ng should not use more capabilities than it is told - or what it needs to -, I'd like to shed some light on why it tries to raise its capabilities despite you telling it to run with less. The reason is actually pretty simple: syslog-ng supports the `owner()` and `group()` options for some destinations, so that it can create output files as a different user than syslog-ng is running under. For this reason, whenever creating such files, it first tries to raise its capabilities, just to make sure it can create them. We currently do not keep track of whether this is required or not, we try to raise anyway. We should probably change that, and only raise capabilities if we really need to. This should solve the issue you are seeing. -- |8]
Also, you can tell it not to manage capabilities with the --no-caps command line option. -- Bazsi On Wed, Apr 18, 2018 at 3:18 PM, Gergely Nagy <algernon@balabit.com> wrote:
Hi!
"Russenberger" == Russenberger Dominik <dominik.russenberger@ terreactive.ch> writes:
Russenberger> Hi List, Russenberger> I recently noticed something very strange: although I run syslog-ng as Russenberger> an unprivileged user (with -u log -g log), newly created logfiles were Russenberger> owned by root. syslog-ng shows up running as user log in ps, as expected.
Russenberger> In my opinion, there are 2 bugs in syslog-ng: Russenberger> * if I tell a daemon to run as unprivileged user I do not expect it to Russenberger> write files as user root. What syslog-ng is doing basically is faking Russenberger> being an unprivileged user, while retaining capabilities which are Russenberger> equivalent to full root permissions. Russenberger> Syslog-ng should imho either run as root, with capabilities; Russenberger> OR as unprivileged user without capabilities (except those Russenberger> explicitly given in --caps) Russenberger> * syslog-ng drops to the capabilities it gets told in --caps, Russenberger> but later g_process_cap_modify() ignores what was specified.
While I agree about your conclusion that syslog-ng should not use more capabilities than it is told - or what it needs to -, I'd like to shed some light on why it tries to raise its capabilities despite you telling it to run with less.
The reason is actually pretty simple: syslog-ng supports the `owner()` and `group()` options for some destinations, so that it can create output files as a different user than syslog-ng is running under. For this reason, whenever creating such files, it first tries to raise its capabilities, just to make sure it can create them. We currently do not keep track of whether this is required or not, we try to raise anyway.
We should probably change that, and only raise capabilities if we really need to. This should solve the issue you are seeing.
-- |8] ____________________________________________________________ __________________ Member info: https://lists.balabit.hu/mailman/listinfo/syslog-ng Documentation: http://www.balabit.com/support/documentation/? product=syslog-ng FAQ: http://www.balabit.com/wiki/syslog-ng-faq
Hi Dominik! I don't know if you got what I replied on IRC, but basically I was wrong there as I only focused on init time capability setting and not on the runtime errors. Sorry. :) I can only agree with @algernon's statement I have found examples of capability mishandling too (although in some points we do check what kind of capability is needed, in affile/file-opener). Reflecting on your topics:
In my opinion, there are 2 bugs in syslog-ng: * if I tell a daemon to run as unprivileged user I do not expect it to write files as user root. What syslog-ng is doing basically is faking being an unprivileged user, while retaining capabilities which are equivalent to full root permissions. Syslog-ng should imho either run as root, with capabilities; OR as unprivileged user without capabilities (except those explicitly given in --caps) * syslog-ng drops to the capabilities it gets told in --caps, but later g_process_cap_modify() ignores what was specified.
1. creating files as root: I can confirm that files are created with root even if --user or --group is used. Although we call setuid() in gprocess at startup, during file opening we use file permissions explicitly from the global config, which defaults to root. I think this is a bug too and we should solve it. What you can do as **workaround** is to set file() options: owner() group() without a value in the configuration. We documented this too: https://syslog-ng.com/documents/html/syslog-ng-ose-latest-guides/en/syslog-n... 2. syslog-ng drops capabilities Syslog-ng sets capabilities given with options --caps at startup. I think the issue here is that some capabilities are hard-wired into syslog-ng (as you have found calls of g_process_cap_modify()). BR, Gabor On Wed, Apr 18, 2018 at 3:49 PM, Scheidler, Balázs <balazs.scheidler@balabit.com> wrote:
Also, you can tell it not to manage capabilities with the --no-caps command line option.
-- Bazsi
On Wed, Apr 18, 2018 at 3:18 PM, Gergely Nagy <algernon@balabit.com> wrote:
Hi!
> "Russenberger" == Russenberger Dominik > <dominik.russenberger@terreactive.ch> writes:
Russenberger> Hi List, Russenberger> I recently noticed something very strange: although I run syslog-ng as Russenberger> an unprivileged user (with -u log -g log), newly created logfiles were Russenberger> owned by root. syslog-ng shows up running as user log in ps, as expected.
Russenberger> In my opinion, there are 2 bugs in syslog-ng: Russenberger> * if I tell a daemon to run as unprivileged user I do not expect it to Russenberger> write files as user root. What syslog-ng is doing basically is faking Russenberger> being an unprivileged user, while retaining capabilities which are Russenberger> equivalent to full root permissions. Russenberger> Syslog-ng should imho either run as root, with capabilities; Russenberger> OR as unprivileged user without capabilities (except those Russenberger> explicitly given in --caps) Russenberger> * syslog-ng drops to the capabilities it gets told in --caps, Russenberger> but later g_process_cap_modify() ignores what was specified.
While I agree about your conclusion that syslog-ng should not use more capabilities than it is told - or what it needs to -, I'd like to shed some light on why it tries to raise its capabilities despite you telling it to run with less.
The reason is actually pretty simple: syslog-ng supports the `owner()` and `group()` options for some destinations, so that it can create output files as a different user than syslog-ng is running under. For this reason, whenever creating such files, it first tries to raise its capabilities, just to make sure it can create them. We currently do not keep track of whether this is required or not, we try to raise anyway.
We should probably change that, and only raise capabilities if we really need to. This should solve the issue you are seeing.
-- |8]
______________________________________________________________________________ Member info: https://lists.balabit.hu/mailman/listinfo/syslog-ng Documentation: http://www.balabit.com/support/documentation/?product=syslog-ng FAQ: http://www.balabit.com/wiki/syslog-ng-faq
______________________________________________________________________________ Member info: https://lists.balabit.hu/mailman/listinfo/syslog-ng Documentation: http://www.balabit.com/support/documentation/?product=syslog-ng FAQ: http://www.balabit.com/wiki/syslog-ng-faq
Hi! A short update on the progress of this report:
"Gabor" == Nagy, Gábor <gabor.nagy@balabit.com> writes:
In my opinion, there are 2 bugs in syslog-ng: >> * if I tell a daemon to run as unprivileged user I do not expect it to >> write files as user root. What syslog-ng is doing basically is faking >> being an unprivileged user, while retaining capabilities which are >> equivalent to full root permissions. >> Syslog-ng should imho either run as root, with capabilities; >> OR as unprivileged user without capabilities (except those >> explicitly given in --caps) >> * syslog-ng drops to the capabilities it gets told in --caps, >> but later g_process_cap_modify() ignores what was specified.
Gabor> 1. creating files as root: Gabor> I can confirm that files are created with root even if --user or Gabor> --group is used. Gabor> Although we call setuid() in gprocess at startup, during file opening Gabor> we use file permissions explicitly from the global config, which Gabor> defaults to root. Gabor> I think this is a bug too and we should solve it. I have opened issue #2002[1], lest we forget about it. [1]: https://github.com/balabit/syslog-ng/issues/2002 Gabor> 2. syslog-ng drops capabilities Gabor> Syslog-ng sets capabilities given with options --caps at startup. Gabor> I think the issue here is that some capabilities are hard-wired into Gabor> syslog-ng (as you have found calls of Gabor> g_process_cap_modify()). The capabilities set with `--caps` are the ones syslog-ng is allowed to obtain during its runtime. It will drop *all* capabilities first, and only take up selected ones when needed, to minimize the possible attack vectors. There may be cases where we try to pick up capabilities when we wouldn't need to (and that's a bug), or if we try to obtain too broad capabilities (also a bug), but dropping all capabilities and only picking up selected ones on demand is a consciously implemented feature. Unless we want to run with elevated capabilities all the time (which would be no different from running as root), we need to have a set of capabilites we can obtain and then drop, on demand. We may need to document the required capabilities and how the whole feature works, better. -- |8]
participants (4)
-
Gergely Nagy
-
Nagy, Gábor
-
Russenberger Dominik
-
Scheidler, Balázs