Skip to content

Commit

Permalink
Merge pull request #5234 from Cropi/libcap-default
Browse files Browse the repository at this point in the history
Add new global config option "libcapng.enable"
  • Loading branch information
rgerhards committed Oct 4, 2023
2 parents 96a065c + 8d33dce commit 69e940b
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 70 deletions.
10 changes: 9 additions & 1 deletion runtime/glbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ static struct cnfparamdescr cnfparamdescr[] = {
{ "shutdown.queue.doublesize", eCmdHdlrBinary, 0 },
{ "debug.files", eCmdHdlrArray, 0 },
{ "debug.whitelist", eCmdHdlrBinary, 0 },
{ "libcapng.default", eCmdHdlrBinary, 0 }
{ "libcapng.default", eCmdHdlrBinary, 0 },
{ "libcapng.enable", eCmdHdlrBinary, 0 },
};
static struct cnfparamblk paramblk =
{ CNFPARAMBLK_VERSION,
Expand Down Expand Up @@ -1214,6 +1215,13 @@ glblDoneLoadCnf(void)
#else
LogError(0, RS_RET_ERR, "rsyslog wasn't "
"compiled with libcap-ng support.");
#endif
} else if(!strcmp(paramblk.descr[i].name, "libcapng.enable")) {
#ifdef ENABLE_LIBCAPNG
loadConf->globals.bCapabilityDropEnabled = (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;
Expand Down
1 change: 1 addition & 0 deletions runtime/rsconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ static void cnfSetDefaults(rsconf_t *pThis)
{
#ifdef ENABLE_LIBCAPNG
pThis->globals.bAbortOnFailedLibcapngSetup = 1;
pThis->globals.bCapabilityDropEnabled = 1;
#endif
pThis->globals.bAbortOnUncleanConfig = 0;
pThis->globals.bAbortOnFailedQueueStartup = 0;
Expand Down
1 change: 1 addition & 0 deletions runtime/rsconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct parsercnf_s {
struct globals_s {
#ifdef ENABLE_LIBCAPNG
int bAbortOnFailedLibcapngSetup;
int bCapabilityDropEnabled;
#endif
int bDebugPrintTemplateList;
int bDebugPrintModuleList;
Expand Down
142 changes: 73 additions & 69 deletions tools/rsyslogd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1636,85 +1636,89 @@ initAll(int argc, char **argv)
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 */
capng_type_t type;
} capabilities_t;

capabilities_t capabilities[] = {
#define CAP_FIELD(code, type) { code, #code, 0 , type}
CAP_FIELD(CAP_BLOCK_SUSPEND, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_CHOWN, CAPNG_EFFECTIVE | CAPNG_PERMITTED ),
CAP_FIELD(CAP_IPC_LOCK, CAPNG_EFFECTIVE | CAPNG_PERMITTED ),
CAP_FIELD(CAP_LEASE, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_NET_ADMIN, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_NET_BIND_SERVICE, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_DAC_OVERRIDE, CAPNG_EFFECTIVE | CAPNG_PERMITTED | CAPNG_BOUNDING_SET),
CAP_FIELD(CAP_SETGID, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SETUID, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYS_ADMIN, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYS_CHROOT, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYS_RESOURCE, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYSLOG, CAPNG_EFFECTIVE | CAPNG_PERMITTED)
#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.
if (loadConf->globals.bCapabilityDropEnabled) {
/*
* Drop capabilities to the necessary 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;
int capng_rc, capng_failed = 0;
typedef struct capabilities_s {
int capability; /* capability code */
const char *name; /* name of the capability to be displayed */
/* is the capability present that is needed by rsyslog? if so we do not drop it */
sbool present;
capng_type_t type;
} capabilities_t;

capabilities_t capabilities[] = {
#define CAP_FIELD(code, type) { code, #code, 0 , type}
CAP_FIELD(CAP_BLOCK_SUSPEND, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_CHOWN, CAPNG_EFFECTIVE | CAPNG_PERMITTED ),
CAP_FIELD(CAP_IPC_LOCK, CAPNG_EFFECTIVE | CAPNG_PERMITTED ),
CAP_FIELD(CAP_LEASE, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_NET_ADMIN, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_NET_BIND_SERVICE, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_DAC_OVERRIDE, CAPNG_EFFECTIVE | CAPNG_PERMITTED | CAPNG_BOUNDING_SET),
CAP_FIELD(CAP_SETGID, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SETUID, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYS_ADMIN, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYS_CHROOT, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYS_RESOURCE, CAPNG_EFFECTIVE | CAPNG_PERMITTED),
CAP_FIELD(CAP_SYSLOG, CAPNG_EFFECTIVE | CAPNG_PERMITTED)
#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, capabilities[i].type,
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;
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, capabilities[i].type,
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);
}
} 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_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);
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("Capabilities were dropped successfully\n");
DBGPRINTF("No capabilities to drop\n");
}
} else {
DBGPRINTF("No capabilities to drop\n");
}
#endif

Expand Down

0 comments on commit 69e940b

Please sign in to comment.