basic/log: make sure header is printed correctly, add test
If log_do_header() was called with overly long parameters, it'd generate improper output. Essentially, it'd be truncated at random point, in particular missing a newline at the end, so it'd run with the next field, usually MESSAGE=. log_do_header is called with parameters from compiled code (file name, lien nubmer, etc), so in practice this was unlikely to ever be a problem, but it is possible. In particular, if systemd was compiled from sources in some deeply nested directory (which happens for example in mock and other build roots), the filename could be very long. As a safety measure, let's truncate all parameters to 256 bytes. So we have 5 fields which are 256 bytes (plus the field name prefix), and a few other fields with fixed width. This must always fit in the 2048 byte buffer. I don't think there's much gain in calculating the required length precisely, since it's a lot of fields and a few bytes allocated on the stack don't matter.
This commit is contained in:
+33
-31
@@ -498,38 +498,40 @@ static int log_do_header(
|
||||
const char *file, int line, const char *func,
|
||||
const char *object_field, const char *object,
|
||||
const char *extra_field, const char *extra) {
|
||||
int r;
|
||||
|
||||
snprintf(header, size,
|
||||
"PRIORITY=%i\n"
|
||||
"SYSLOG_FACILITY=%i\n"
|
||||
"%s%s%s"
|
||||
"%s%.*i%s"
|
||||
"%s%s%s"
|
||||
"%s%.*i%s"
|
||||
"%s%s%s"
|
||||
"%s%s%s"
|
||||
"SYSLOG_IDENTIFIER=%s\n",
|
||||
LOG_PRI(level),
|
||||
LOG_FAC(level),
|
||||
isempty(file) ? "" : "CODE_FILE=",
|
||||
isempty(file) ? "" : file,
|
||||
isempty(file) ? "" : "\n",
|
||||
line ? "CODE_LINE=" : "",
|
||||
line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
|
||||
line ? "\n" : "",
|
||||
isempty(func) ? "" : "CODE_FUNC=",
|
||||
isempty(func) ? "" : func,
|
||||
isempty(func) ? "" : "\n",
|
||||
error ? "ERRNO=" : "",
|
||||
error ? 1 : 0, error,
|
||||
error ? "\n" : "",
|
||||
isempty(object) ? "" : object_field,
|
||||
isempty(object) ? "" : object,
|
||||
isempty(object) ? "" : "\n",
|
||||
isempty(extra) ? "" : extra_field,
|
||||
isempty(extra) ? "" : extra,
|
||||
isempty(extra) ? "" : "\n",
|
||||
program_invocation_short_name);
|
||||
r = snprintf(header, size,
|
||||
"PRIORITY=%i\n"
|
||||
"SYSLOG_FACILITY=%i\n"
|
||||
"%s%.256s%s" /* CODE_FILE */
|
||||
"%s%.*i%s" /* CODE_LINE */
|
||||
"%s%.256s%s" /* CODE_FUNC */
|
||||
"%s%.*i%s" /* ERRNO */
|
||||
"%s%.256s%s" /* object */
|
||||
"%s%.256s%s" /* extra */
|
||||
"SYSLOG_IDENTIFIER=%.256s\n",
|
||||
LOG_PRI(level),
|
||||
LOG_FAC(level),
|
||||
isempty(file) ? "" : "CODE_FILE=",
|
||||
isempty(file) ? "" : file,
|
||||
isempty(file) ? "" : "\n",
|
||||
line ? "CODE_LINE=" : "",
|
||||
line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
|
||||
line ? "\n" : "",
|
||||
isempty(func) ? "" : "CODE_FUNC=",
|
||||
isempty(func) ? "" : func,
|
||||
isempty(func) ? "" : "\n",
|
||||
error ? "ERRNO=" : "",
|
||||
error ? 1 : 0, error,
|
||||
error ? "\n" : "",
|
||||
isempty(object) ? "" : object_field,
|
||||
isempty(object) ? "" : object,
|
||||
isempty(object) ? "" : "\n",
|
||||
isempty(extra) ? "" : extra_field,
|
||||
isempty(extra) ? "" : extra,
|
||||
isempty(extra) ? "" : "\n",
|
||||
program_invocation_short_name);
|
||||
assert((size_t) r < size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user