Skip to content

Commit

Permalink
drivers/dstate.{c,h}: add vdstate_setinfo(), vdstate_addenum() and ve…
Browse files Browse the repository at this point in the history
…rsions for hardened dynamic format string support [networkupstools#2450]

Signed-off-by: Jim Klimov <[email protected]>
  • Loading branch information
jimklimov committed May 31, 2024
1 parent 4b3e66d commit aec902c
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 7 deletions.
84 changes: 77 additions & 7 deletions drivers/dstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,13 +1191,11 @@ int dstate_poll_fds(struct timeval timeout, TYPE_FD arg_extrafd)
* COMMON
******************************************************************/

int dstate_setinfo(const char *var, const char *fmt, ...)
int vdstate_setinfo(const char *var, const char *fmt, va_list ap)
{
int ret;
char value[ST_MAX_VALUE_LEN];
va_list ap;

va_start(ap, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
Expand All @@ -1211,7 +1209,6 @@ int dstate_setinfo(const char *var, const char *fmt, ...)
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(ap);

ret = state_setinfo(&dtree_root, var, value);

Expand All @@ -1222,10 +1219,9 @@ int dstate_setinfo(const char *var, const char *fmt, ...)
return ret;
}

int dstate_addenum(const char *var, const char *fmt, ...)
int dstate_setinfo(const char *var, const char *fmt, ...)
{
int ret;
char value[ST_MAX_VALUE_LEN];
va_list ap;

va_start(ap, fmt);
Expand All @@ -1238,12 +1234,62 @@ int dstate_addenum(const char *var, const char *fmt, ...)
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vsnprintf(value, sizeof(value), fmt, ap);
ret = vdstate_setinfo(var, fmt, ap);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(ap);

return ret;
}

int dstate_setinfo_dynamic(const char *var, const char *fmt_dynamic, const char *fmt_reference, ...)
{
if (!var || validate_formatting_string(fmt_dynamic, fmt_reference) < 0) {
return -1;
} else {
int ret;
va_list ap;

va_start(ap, fmt_reference);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
ret = vdstate_setinfo(var, fmt_dynamic, ap);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(ap);

return ret;
}
}

int vdstate_addenum(const char *var, const char *fmt, va_list ap)
{
int ret;
char value[ST_MAX_VALUE_LEN];

#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vsnprintf(value, sizeof(value), fmt, ap);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif

ret = state_addenum(dtree_root, var, value);

if (ret == 1) {
Expand All @@ -1253,6 +1299,30 @@ int dstate_addenum(const char *var, const char *fmt, ...)
return ret;
}

int dstate_addenum(const char *var, const char *fmt, ...)
{
int ret;
va_list ap;

va_start(ap, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
ret = vdstate_addenum(var, fmt, ap);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(ap);

return ret;
}

int dstate_addrange(const char *var, const int min, const int max)
{
int ret;
Expand Down
6 changes: 6 additions & 0 deletions drivers/dstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,16 @@ typedef struct conn_s {

char * dstate_init(const char *prog, const char *devname);
int dstate_poll_fds(struct timeval timeout, TYPE_FD extrafd);
int vdstate_setinfo(const char *var, const char *fmt, va_list ap);
int dstate_setinfo(const char *var, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
int dstate_setinfo_dynamic(const char *var, const char *fmt_dynamic, const char *fmt_reference, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
int vdstate_addenum(const char *var, const char *fmt, va_list ap);
int dstate_addenum(const char *var, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
int dstate_addenum_dynamic(const char *var, const char *fmt_dynamic, const char *fmt_reference, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
int dstate_addrange(const char *var, const int min, const int max);
void dstate_setflags(const char *var, int flags);
void dstate_addflags(const char *var, const int addflags);
Expand Down

0 comments on commit aec902c

Please sign in to comment.