mirror of
https://salsa.debian.org/ha-team/libqb
synced 2026-08-08 11:14:07 +00:00
LOG: change qb_vsprintf_serialize() into qb_vsnprintf_serialize()
This is to prevent overwriting the ringbuffer. Also remove stpcpy() as it is not used anymore. Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
parent
8820724f59
commit
a55554efb1
@ -200,7 +200,7 @@ AM_CONDITIONAL(HAVE_KQUEUE,
|
||||
[test "x$ac_cv_func_kqueue" = xyes])
|
||||
|
||||
AC_CONFIG_LIBOBJ_DIR(lib)
|
||||
AC_REPLACE_FUNCS(strlcpy strlcat strchrnul stpcpy)
|
||||
AC_REPLACE_FUNCS(strlcpy strlcat strchrnul)
|
||||
|
||||
## local defines
|
||||
PACKAGE_FEATURES=""
|
||||
|
||||
@ -162,10 +162,6 @@ size_t strlcpy(char *dest, const char *src, size_t maxlen);
|
||||
size_t strlcat(char *dest, const char *src, size_t maxlen);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STPCPY
|
||||
char * stpcpy(char *dest, const char *src);
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
@ -95,11 +95,13 @@ _blackbox_vlogger(int32_t target,
|
||||
chunk += sizeof(uint32_t);
|
||||
|
||||
/* log message */
|
||||
msg_len = qb_vsprintf_serialize(chunk, cs->format, ap);
|
||||
if(msg_len > QB_LOG_MAX_LEN) {
|
||||
msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN, cs->format, ap);
|
||||
if(msg_len >= QB_LOG_MAX_LEN) {
|
||||
chunk = msg_len_pt + sizeof(uint32_t); /* Reset */
|
||||
|
||||
msg_len = qb_vsprintf_serialize(chunk, "Log message too long to be stored in the blackbox. Maximum is QB_LOG_MAX_LEN" , ap);
|
||||
msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN,
|
||||
"Log message too long to be stored in the blackbox. "\
|
||||
"Maximum is QB_LOG_MAX_LEN" , ap);
|
||||
actual_size += msg_len;
|
||||
}
|
||||
|
||||
|
||||
@ -379,18 +379,16 @@ qb_log_target_format(int32_t target,
|
||||
}
|
||||
|
||||
size_t
|
||||
qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap)
|
||||
qb_vsnprintf_serialize(char *serialize, size_t max_len,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
char *format;
|
||||
char *p;
|
||||
uint32_t location = 0;
|
||||
int type_long = 0;
|
||||
int type_longlong = 0;
|
||||
int sformat_length = 0;
|
||||
int sformat_precision = 0;
|
||||
|
||||
p = stpcpy(serialize, fmt);
|
||||
location = p - serialize + 1;
|
||||
uint32_t location = strlcpy(serialize, fmt, max_len) + 1;
|
||||
|
||||
format = (char *)fmt;
|
||||
for (;;) {
|
||||
@ -433,6 +431,9 @@ reprocess:
|
||||
goto reprocess;
|
||||
case '*': /* variable field width, save */ {
|
||||
int arg_int = va_arg(ap, int);
|
||||
if (location + sizeof (int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
memcpy(&serialize[location], &arg_int, sizeof (int));
|
||||
location += sizeof(int);
|
||||
format++;
|
||||
@ -456,6 +457,9 @@ reprocess:
|
||||
if (type_long) {
|
||||
long int arg_int;
|
||||
|
||||
if (location + sizeof (long int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, long int);
|
||||
memcpy(&serialize[location], &arg_int,
|
||||
sizeof(long int));
|
||||
@ -465,6 +469,9 @@ reprocess:
|
||||
} else if (type_longlong) {
|
||||
long long int arg_int;
|
||||
|
||||
if (location + sizeof (long long int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, long long int);
|
||||
memcpy(&serialize[location], &arg_int,
|
||||
sizeof(long long int));
|
||||
@ -474,6 +481,9 @@ reprocess:
|
||||
} else {
|
||||
int arg_int;
|
||||
|
||||
if (location + sizeof (int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, int);
|
||||
memcpy(&serialize[location], &arg_int,
|
||||
sizeof(int));
|
||||
@ -492,6 +502,9 @@ reprocess:
|
||||
{
|
||||
double arg_double;
|
||||
|
||||
if (location + sizeof (double) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_double = va_arg(ap, double);
|
||||
memcpy (&serialize[location], &arg_double, sizeof (double));
|
||||
location += sizeof(double);
|
||||
@ -503,6 +516,9 @@ reprocess:
|
||||
int arg_int;
|
||||
unsigned char arg_char;
|
||||
|
||||
if (location + sizeof (unsigned int) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
arg_int = va_arg(ap, unsigned int);
|
||||
arg_char = (unsigned char)arg_int;
|
||||
memcpy (&serialize[location], &arg_char, sizeof (unsigned char));
|
||||
@ -514,24 +530,38 @@ reprocess:
|
||||
char *arg_string;
|
||||
arg_string = va_arg(ap, char *);
|
||||
if (arg_string == NULL) {
|
||||
p = stpcpy(&serialize[location], "(null)");
|
||||
location += strlcpy(&serialize[location],
|
||||
"(null)",
|
||||
QB_MIN(strlen("(null)") + 1,
|
||||
max_len - location));
|
||||
} else if (sformat_length) {
|
||||
p = stpncpy(&serialize[location], arg_string, sformat_length);
|
||||
serialize[location+sformat_length] = 0;
|
||||
location += strlcpy(&serialize[location],
|
||||
arg_string,
|
||||
QB_MIN(sformat_length + 1,
|
||||
(max_len - location)));
|
||||
} else {
|
||||
p = stpcpy(&serialize[location], arg_string);
|
||||
location += strlcpy(&serialize[location],
|
||||
arg_string,
|
||||
QB_MIN(strlen(arg_string) + 1,
|
||||
max_len - location));
|
||||
}
|
||||
location += p - &serialize[location] + 1;
|
||||
location++;
|
||||
break;
|
||||
}
|
||||
case 'p':
|
||||
{
|
||||
ptrdiff_t arg_pointer = va_arg(ap, ptrdiff_t);
|
||||
if (location + sizeof (ptrdiff_t) > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
memcpy(&serialize[location], &arg_pointer, sizeof(ptrdiff_t));
|
||||
location += sizeof(ptrdiff_t);
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
if (location + 1 > max_len) {
|
||||
return max_len;
|
||||
}
|
||||
serialize[location++] = '%';
|
||||
sformat_length = 0;
|
||||
sformat_precision = 0;
|
||||
@ -558,14 +588,15 @@ qb_vsnprintf_deserialize(char *string, size_t str_len, const char *buf)
|
||||
int type_longlong = 0;
|
||||
int len;
|
||||
|
||||
string[0] = '\0';
|
||||
format = (char *)buf;
|
||||
for (;;) {
|
||||
type_long = 0;
|
||||
type_longlong = 0;
|
||||
p = strchrnul((const char *)format, '%');
|
||||
if (*p == '\0') {
|
||||
p = stpcpy(&string[location], format);
|
||||
location += p - &string[location] + 1;
|
||||
location = strlcat(&string[location], format, str_len) + 1;
|
||||
p += location;
|
||||
break;
|
||||
}
|
||||
/* copy from current to the next % */
|
||||
|
||||
@ -95,7 +95,7 @@ struct qb_log_callsite *qb_log_dcs_get(int32_t *newly_created,
|
||||
uint32_t tags);
|
||||
|
||||
const char * qb_log_priority2str(uint8_t priority);
|
||||
size_t qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap);
|
||||
size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap);
|
||||
size_t qb_vsnprintf_deserialize(char *string, size_t str_len, const char *buf);
|
||||
|
||||
void qb_log_target_format_static(int32_t target, const char * format, char *output_buffer);
|
||||
|
||||
38
lib/stpcpy.c
38
lib/stpcpy.c
@ -1,38 +0,0 @@
|
||||
/* stpcpy.c -- copy a string and return pointer to end of new string
|
||||
Copyright (C) 1992, 1995, 1997-1998, 2006, 2009-2012 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2.1 of the License, or any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
|
||||
char *
|
||||
stpcpy (char *dest, const char *src)
|
||||
{
|
||||
register char *d = dest;
|
||||
register const char *s = src;
|
||||
|
||||
do
|
||||
*d++ = *s;
|
||||
while (*s++ != '\0');
|
||||
|
||||
return d - 1;
|
||||
}
|
||||
@ -29,7 +29,7 @@
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qblog.h>
|
||||
|
||||
extern size_t qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap);
|
||||
extern size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap);
|
||||
extern size_t qb_vsnprintf_deserialize(char *string, size_t strlen, const char *buf);
|
||||
|
||||
|
||||
@ -40,11 +40,22 @@ format_this(char *out, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qb_vsprintf_serialize(buf, fmt, ap);
|
||||
qb_vsnprintf_serialize(buf, QB_LOG_MAX_LEN, fmt, ap);
|
||||
qb_vsnprintf_deserialize(out, QB_LOG_MAX_LEN, buf);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
format_this_up_to(char *out, size_t max_len, const char *fmt, ...)
|
||||
{
|
||||
char buf[QB_LOG_MAX_LEN];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qb_vsnprintf_serialize(buf, max_len, fmt, ap);
|
||||
qb_vsnprintf_deserialize(out, QB_LOG_MAX_LEN, buf);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
START_TEST(test_va_serialize)
|
||||
{
|
||||
@ -89,6 +100,9 @@ START_TEST(test_va_serialize)
|
||||
|
||||
format_this(buf, ":%*d:", 8, 96);
|
||||
ck_assert_str_eq(buf, ": 96:");
|
||||
|
||||
format_this_up_to(buf, 11, "123456789____");
|
||||
ck_assert_str_eq(buf, "123456789_");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -559,12 +573,31 @@ END_TEST
|
||||
|
||||
START_TEST(test_log_long_msg)
|
||||
{
|
||||
qb_log_init("test", LOG_USER, LOG_DEBUG);
|
||||
qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
|
||||
qb_log_format_set(QB_LOG_SYSLOG, "%b");
|
||||
int lpc;
|
||||
int rc;
|
||||
int i, max = 1000;
|
||||
char *buffer = calloc(1, max);
|
||||
|
||||
qb_log(LOG_ERR, "QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07 QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07 QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07");
|
||||
qb_log_init("test", LOG_USER, LOG_DEBUG);
|
||||
rc = qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 1024);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
|
||||
QB_LOG_FILTER_FILE, "*", LOG_TRACE);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
|
||||
for (lpc = 500; lpc < max; lpc++) {
|
||||
lpc++;
|
||||
for(i = 0; i < max; i++) {
|
||||
buffer[i] = 'a' + (i % 10);
|
||||
}
|
||||
buffer[lpc%600] = 0;
|
||||
qb_log(LOG_INFO, "Message %d %d - %s", lpc, lpc%600, buffer);
|
||||
}
|
||||
qb_log_fini();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user