core: add global parameter "security.abortOnIDResolutionFail"

This parameter controls whether or not rsyslog aborts when a name ID
lookup fails (for user and group names). This is necessary as a security
measure, as otherwise the wrong permissions can be assigned or privileges
are not dropped.

CHANGE OF BEHAVIOR
The default for this parameter is "on". In previous versions, the default
was "off" (by virtue) of this parameter not existing. As such, existing
configurations may now error out.

We have decided to accept this change of behavior because of the potential
security implications.

closes https://github.com/rsyslog/rsyslog/issues/4164
This commit is contained in:
Rainer Gerhards 2020-02-11 12:54:19 +01:00
parent 3858b85f74
commit cbcaf2c7e5
No known key found for this signature in database
GPG Key ID: 0CB6B2A8BE80B499
5 changed files with 35 additions and 11 deletions

View File

@ -3,7 +3,7 @@
*
* File begun on 2007-07-30 by RGerhards
*
* Copyright (C) 2007-2016 Adiscon GmbH.
* Copyright (C) 2007-2020 Adiscon GmbH.
*
* This file is part of rsyslog.
*
@ -41,6 +41,7 @@
#include "errmsg.h"
#include "srUtils.h"
#include "unicode-helper.h"
#include "rsconf.h"
#include "parserif.h"
@ -352,8 +353,13 @@ static rsRetVal doGetGID(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *p
assert(*pp != NULL);
if(getSubString(pp, (char*) szName, sizeof(szName), ' ') != 0) {
LogError(0, RS_RET_NOT_FOUND, "could not extract group name");
ABORT_FINALIZE(RS_RET_NOT_FOUND);
if(loadConf->globals.abortOnIDResolutionFail) {
fprintf(stderr, "could not extract group name: %s\n", (char*)szName);
exit(1); /* good exit */
} else {
LogError(0, RS_RET_NOT_FOUND, "could not extract group name");
ABORT_FINALIZE(RS_RET_NOT_FOUND);
}
}
do {
@ -374,6 +380,10 @@ static rsRetVal doGetGID(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *p
LogError(0, RS_RET_NOT_FOUND, "ID for group '%s' could not be found", szName);
}
iRet = RS_RET_NOT_FOUND;
if(loadConf->globals.abortOnIDResolutionFail) {
fprintf(stderr, "ID for group '%s' could not be found or error\n", szName);
exit(1); /* good exit */
}
} else {
if(pSetHdlr == NULL) {
/* we should set value directly to var */
@ -408,15 +418,25 @@ static rsRetVal doGetUID(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *p
assert(*pp != NULL);
if(getSubString(pp, (char*) szName, sizeof(szName), ' ') != 0) {
LogError(0, RS_RET_NOT_FOUND, "could not extract user name");
ABORT_FINALIZE(RS_RET_NOT_FOUND);
if(loadConf->globals.abortOnIDResolutionFail) {
fprintf(stderr, "could not extract user name: %s\n", (char*)szName);
exit(1); /* good exit */
} else {
LogError(0, RS_RET_NOT_FOUND, "could not extract user name");
ABORT_FINALIZE(RS_RET_NOT_FOUND);
}
}
getpwnam_r((char*)szName, &pwBuf, stringBuf, sizeof(stringBuf), &ppwBuf);
if(ppwBuf == NULL) {
LogError(0, RS_RET_NOT_FOUND, "ID for user '%s' could not be found or error", (char*)szName);
iRet = RS_RET_NOT_FOUND;
if(loadConf->globals.abortOnIDResolutionFail) {
fprintf(stderr, "ID for user '%s' could not be found or error\n", (char*)szName);
exit(1); /* good exit */
} else {
LogError(0, RS_RET_NOT_FOUND, "ID for user '%s' could not be found or error", (char*)szName);
iRet = RS_RET_NOT_FOUND;
}
} else {
if(pSetHdlr == NULL) {
/* we should set value directly to var */

View File

@ -7,7 +7,7 @@
*
* Module begun 2008-04-16 by Rainer Gerhards
*
* Copyright 2008-2019 Rainer Gerhards and Adiscon GmbH.
* Copyright 2008-2020 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@ -209,6 +209,7 @@ static struct cnfparamdescr cnfparamdescr[] = {
{ "environment", eCmdHdlrArray, 0 },
{ "processinternalmessages", eCmdHdlrBinary, 0 },
{ "umask", eCmdHdlrFileCreateMode, 0 },
{ "security.abortonidresolutionfail", eCmdHdlrBinary, 0 },
{ "internal.developeronly.options", eCmdHdlrInt, 0 },
{ "internalmsg.ratelimit.interval", eCmdHdlrPositiveInt, 0 },
{ "internalmsg.ratelimit.burst", eCmdHdlrPositiveInt, 0 },
@ -1440,6 +1441,8 @@ glblDoneLoadCnf(void)
glblInputTimeoutShutdown = (int) cnfparamvals[i].val.d.n;
} else if(!strcmp(paramblk.descr[i].name, "privdrop.group.keepsupplemental")) {
loadConf->globals.gidDropPrivKeepSupplemental = (int) cnfparamvals[i].val.d.n;
} else if(!strcmp(paramblk.descr[i].name, "security.abortonidresolutionfail")) {
loadConf->globals.abortOnIDResolutionFail = (int) cnfparamvals[i].val.d.n;
} else if(!strcmp(paramblk.descr[i].name, "net.acladdhostnameonfail")) {
*(net.pACLAddHostnameOnFail) = (int) cnfparamvals[i].val.d.n;
} else if(!strcmp(paramblk.descr[i].name, "net.aclresolvehostname")) {

View File

@ -79,7 +79,6 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
SIMP_PROP(ParserEscape8BitCharactersOnReceive, int)
SIMP_PROP(ParserEscapeControlCharacterTab, int)
SIMP_PROP(ParserEscapeControlCharactersCStyle, int)
/* added v3, 2009-06-30 */
rsRetVal (*GenerateLocalHostNameProperty)(void);
prop_t* (*GetLocalHostNameProp)(void);

View File

@ -2,7 +2,7 @@
*
* Module begun 2011-04-19 by Rainer Gerhards
*
* Copyright 2011-2019 Adiscon GmbH.
* Copyright 2011-2020 Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@ -156,6 +156,7 @@ static void cnfSetDefaults(rsconf_t *pThis)
pThis->globals.maxErrMsgToStderr = -1;
pThis->globals.umask = -1;
pThis->globals.gidDropPrivKeepSupplemental = 0;
pThis->globals.abortOnIDResolutionFail = 1;
pThis->templates.root = NULL;
pThis->templates.last = NULL;
pThis->templates.lastStatic = NULL;

View File

@ -1,6 +1,6 @@
/* The rsconf object. It models a complete rsyslog configuration.
*
* Copyright 2011-2016 Rainer Gerhards and Adiscon GmbH.
* Copyright 2011-2020 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@ -73,6 +73,7 @@ struct globals_s {
int uidDropPriv; /* user-id to which priveleges should be dropped to */
int gidDropPriv; /* group-id to which priveleges should be dropped to */
int gidDropPrivKeepSupplemental; /* keep supplemental groups when dropping? */
int abortOnIDResolutionFail;
int umask; /* umask to use */
uchar *pszConfDAGFile; /* name of config DAG file, non-NULL means generate one */