/
githubmirror
/
rsyslog
Обзор
Документация
Войти
/
githubmirror
/
rsyslog
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
plugins/mmfields/mmfields.c
258 строк
7 KB
Rainer Gerhards
hardning: harden config parameter ownership and OOM cleanup
09 май 2026, 12:50
Не верифицирован
09 май 2026, 12:50
e1e3d1b
Код
Авторство
О чём код?
/* mmfields.c * Parse all fields of the message into structured data inside the * JSON tree. * * Copyright 2013 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <signal.h> #include <errno.h> #include <unistd.h> #include <stdint.h> #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("mmfields") DEF_OMOD_STATIC_DATA; /* config variables */ /* define operation modes we have */ #define SIMPLE_MODE 0 /* just overwrite */ #define REWRITE_MODE 1 /* rewrite IP address, canoninized */ typedef struct _instanceData { char separator; uchar *jsonRoot; /**< container where to store fields */ } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = {{"separator", eCmdHdlrGetChar, 0}, {"jsonroot", eCmdHdlrString, 0}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; free(pData->jsonRoot); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance static inline void setInstParamDefaults(instanceData *pData) { pData->separator = ','; pData->jsonRoot = NULL; } BEGINnewActInst struct cnfparamvals *pvals; int i; CODESTARTnewActInst; DBGPRINTF("newActInst (mmfields)\n"); if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "separator")) { pData->separator = es_getBufAddr(pvals[i].val.d.estr)[0]; } else if (!strcmp(actpblk.descr[i].name, "jsonroot")) { CHKmalloc(pData->jsonRoot = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); } else { dbgprintf( "mmfields: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } if (pData->jsonRoot == NULL) { CHKmalloc(pData->jsonRoot = (uchar *)strdup("!")); } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume static rsRetVal extractField(instanceData *pData, uchar *msgtext, int lenMsg, int *curridx, uchar *fieldbuf) { int i, j; DEFiRet; i = *curridx; j = 0; while (i < lenMsg && msgtext[i] != pData->separator) { fieldbuf[j++] = msgtext[i++]; } fieldbuf[j] = '\0'; if (i < lenMsg) ++i; *curridx = i; RETiRet; } static rsRetVal parse_fields(instanceData *pData, smsg_t *pMsg, uchar *msgtext, int lenMsg) { uchar fieldbuf[32 * 1024]; uchar fieldname[512]; struct json_object *json; struct json_object *jval; int field; uchar *buf; int currIdx = 0; DEFiRet; if (lenMsg < (int)sizeof(fieldbuf)) { buf = fieldbuf; } else { CHKmalloc(buf = malloc(lenMsg + 1)); } json = json_object_new_object(); if (json == NULL) { ABORT_FINALIZE(RS_RET_ERR); } field = 1; while (currIdx < lenMsg) { CHKiRet(extractField(pData, msgtext, lenMsg, &currIdx, buf)); DBGPRINTF("mmfields: field %d: '%s'\n", field, buf); snprintf((char *)fieldname, sizeof(fieldname), "f%d", field); fieldname[sizeof(fieldname) - 1] = '\0'; jval = json_object_new_string((char *)buf); json_object_object_add(json, (char *)fieldname, jval); field++; } msgAddJSON(pMsg, pData->jsonRoot, json, 0, 0); finalize_it: if (buf != fieldbuf) free(buf); RETiRet; } BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **)pMsgData; smsg_t *pMsg = ppMsg[0]; uchar *msg; int lenMsg; CODESTARTdoAction; lenMsg = getMSGLen(pMsg); msg = getMSG(pMsg); iRet = parse_fields(pWrkrData->pData, pMsg, msg, lenMsg); ENDdoAction NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("mmfields: module compiled with rsyslog version %s.\n", VERSION); ENDmodInit