diff -up rsyslog-8.2102.0/runtime/glbl.c.orig rsyslog-8.2102.0/runtime/glbl.c --- rsyslog-8.2102.0/runtime/glbl.c.orig 2023-07-14 09:32:51.781256794 +0200 +++ rsyslog-8.2102.0/runtime/glbl.c 2023-07-14 09:34:34.061315870 +0200 @@ -230,7 +230,8 @@ static struct cnfparamdescr cnfparamdesc { "reverselookup.cache.ttl.enable", eCmdHdlrBinary, 0 }, { "shutdown.queue.doublesize", eCmdHdlrBinary, 0 }, { "debug.files", eCmdHdlrArray, 0 }, - { "debug.whitelist", eCmdHdlrBinary, 0 } + { "debug.whitelist", eCmdHdlrBinary, 0 }, + { "libcapng.default", eCmdHdlrBinary, 0 } }; static struct cnfparamblk paramblk = { CNFPARAMBLK_VERSION, @@ -1315,6 +1316,13 @@ glblDoneLoadCnf(void) if(!strcmp(paramblk.descr[i].name, "workdirectory")) { cstr = (uchar*) es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setWorkDir(NULL, cstr); + } else if(!strcmp(paramblk.descr[i].name, "libcapng.default")) { +#ifdef ENABLE_LIBCAPNG + loadConf->globals.bAbortOnFailedLibcapngSetup = (int) cnfparamvals[i].val.d.n; +#else + LogError(0, RS_RET_ERR, "rsyslog wasn't " + "compiled with libcap-ng support."); +#endif } else if(!strcmp(paramblk.descr[i].name, "variables.casesensitive")) { const int val = (int) cnfparamvals[i].val.d.n; fjson_global_do_case_sensitive_comparison(val); diff -up rsyslog-8.2102.0/runtime/rsconf.c.orig rsyslog-8.2102.0/runtime/rsconf.c --- rsyslog-8.2102.0/runtime/rsconf.c.orig 2023-07-14 09:32:56.923259764 +0200 +++ rsyslog-8.2102.0/runtime/rsconf.c 2023-07-14 09:34:47.722323759 +0200 @@ -146,6 +146,9 @@ int rsconfNeedDropPriv(rsconf_t *const c static void cnfSetDefaults(rsconf_t *pThis) { +#ifdef ENABLE_LIBCAPNG + pThis->globals.bAbortOnFailedLibcapngSetup = 1; +#endif pThis->globals.bAbortOnUncleanConfig = 0; pThis->globals.bReduceRepeatMsgs = 0; pThis->globals.bDebugPrintTemplateList = 1; diff -up rsyslog-8.2102.0/runtime/rsconf.h.orig rsyslog-8.2102.0/runtime/rsconf.h --- rsyslog-8.2102.0/runtime/rsconf.h.orig 2023-07-14 09:33:02.575263028 +0200 +++ rsyslog-8.2102.0/runtime/rsconf.h 2023-07-14 09:35:29.265347750 +0200 @@ -61,6 +61,9 @@ struct queuecnf_s { * be re-set as often as the user likes). */ struct globals_s { +#ifdef ENABLE_LIBCAPNG + int bAbortOnFailedLibcapngSetup; +#endif int bDebugPrintTemplateList; int bDebugPrintModuleList; int bDebugPrintCfSysLineHandlerList; diff -up rsyslog-8.2102.0/tools/rsyslogd.c.orig rsyslog-8.2102.0/tools/rsyslogd.c --- rsyslog-8.2102.0/tools/rsyslogd.c.orig 2023-07-14 09:29:13.038130459 +0200 +++ rsyslog-8.2102.0/tools/rsyslogd.c 2023-07-14 09:31:58.575226065 +0200 @@ -1557,6 +1557,88 @@ initAll(int argc, char **argv) resetErrMsgsFlag(); localRet = rsconf.Load(&ourConf, ConfFile); +#ifdef ENABLE_LIBCAPNG + /* + * Drop capabilities to the necessary set + */ + int capng_rc, capng_failed = 0; + typedef struct capabilities_s { + int capability; /* capability code */ + const char *name; /* name of the capability to be displayed */ + sbool present; /* is the capability present that is needed by rsyslog? if so we do not drop it */ + } capabilities_t; + + capabilities_t capabilities[] = { + #define CAP_FIELD(code) { code, #code, 0 } + CAP_FIELD(CAP_BLOCK_SUSPEND), + CAP_FIELD(CAP_CHOWN), + CAP_FIELD(CAP_IPC_LOCK), + CAP_FIELD(CAP_LEASE), + CAP_FIELD(CAP_NET_ADMIN), + CAP_FIELD(CAP_NET_BIND_SERVICE), + CAP_FIELD(CAP_DAC_OVERRIDE), + CAP_FIELD(CAP_SETGID), + CAP_FIELD(CAP_SETUID), + CAP_FIELD(CAP_SYS_ADMIN), + CAP_FIELD(CAP_SYS_CHROOT), + CAP_FIELD(CAP_SYS_RESOURCE), + CAP_FIELD(CAP_SYSLOG) + #undef CAP_FIELD + }; + + if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE) { + /* Examine which capabilities are available to us, so we do not try to + drop something that is not present. We need to do this in two steps, + because capng_clear clears the capability set. In the second step, + we add back those caps, which were present before clearing the selected + posix capabilities set. + */ + unsigned long caps_len = sizeof(capabilities) / sizeof(capabilities_t); + for (unsigned long i = 0; i < caps_len; i++) { + if (capng_have_capability(CAPNG_EFFECTIVE, capabilities[i].capability)) { + capabilities[i].present = 1; + } + } + + capng_clear(CAPNG_SELECT_BOTH); + + for (unsigned long i = 0; i < caps_len; i++) { + if (capabilities[i].present) { + DBGPRINTF("The %s capability is present, " + "will try to preserve it.\n", capabilities[i].name); + if ((capng_rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, + capabilities[i].capability)) != 0) { + LogError(0, RS_RET_LIBCAPNG_ERR, + "could not update the internal posix capabilities settings " + "based on the options passed to it, capng_update=%d", capng_rc); + capng_failed = 1; + } + } else { + DBGPRINTF("The %s capability is not present, " + "will not try to preserve it.\n", capabilities[i].name); + } + } + + if ((capng_rc = capng_apply(CAPNG_SELECT_BOTH)) != 0) { + LogError(0, RS_RET_LIBCAPNG_ERR, + "could not transfer the specified internal posix capabilities " + "settings to the kernel, capng_apply=%d", capng_rc); + capng_failed = 1; + } + + if (capng_failed) { + DBGPRINTF("Capabilities were not dropped successfully.\n"); + if (loadConf->globals.bAbortOnFailedLibcapngSetup) { + ABORT_FINALIZE(RS_RET_LIBCAPNG_ERR); + } + } else { + DBGPRINTF("Capabilities were dropped successfully\n"); + } + } else { + DBGPRINTF("No capabilities to drop\n"); + } +#endif + if(fp_rs_full_conf_output != NULL) { if(fp_rs_full_conf_output != stdout) { fclose(fp_rs_full_conf_output); @@ -2147,45 +2229,6 @@ main(int argc, char **argv) bProcessInternalMessages = 1; dbgClassInit(); -#ifdef ENABLE_LIBCAPNG - /* - * Drop capabilities to the necessary set - */ - int capng_rc; - capng_clear(CAPNG_SELECT_BOTH); - - if ((capng_rc = capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, - CAP_BLOCK_SUSPEND, - CAP_CHOWN, - CAP_IPC_LOCK, - CAP_LEASE, - CAP_NET_ADMIN, - CAP_NET_BIND_SERVICE, - CAP_SETGID, - CAP_SETUID, - CAP_DAC_OVERRIDE, - CAP_NET_RAW, - CAP_SYS_ADMIN, - CAP_SYS_CHROOT, - CAP_SYS_RESOURCE, - CAP_SYSLOG, - -1 - )) != 0) { - LogError(0, RS_RET_LIBCAPNG_ERR, - "could not update the internal posix capabilities settings " - "based on the options passed to it, capng_updatev=%d\n", capng_rc); - exit(-1); - } - - if ((capng_rc = capng_apply(CAPNG_SELECT_BOTH)) != 0) { - LogError(0, RS_RET_LIBCAPNG_ERR, - "could not transfer the specified internal posix capabilities " - "settings to the kernel, capng_apply=%d\n", capng_rc); - exit(-1); - } - DBGPRINTF("Capabilities were dropped successfully\n"); -#endif - initAll(argc, argv); #ifdef HAVE_LIBSYSTEMD sd_notify(0, "READY=1");