From 5ffa8c818120e35c89becd938d160235c069dd12 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 27 Jan 2015 08:00:11 -0500 Subject: [PATCH] Add a snprinf wrapper which checks that the buffer was big enough If we scale our buffer to be wide enough for the format string, we should expect that the calculation was correct. char_array_0() invocations are removed, since snprintf nul-terminates the output in any case. A similar wrapper is used for strftime calls, but only in timedatectl.c. --- src/core/automount.c | 12 ++-- src/core/job.c | 1 - src/core/main.c | 7 +-- src/core/selinux-access.c | 14 ++--- src/core/unit.c | 1 - src/fsck/fsck.c | 5 +- src/journal-remote/journal-remote.c | 4 +- src/journal-remote/journal-upload-journal.c | 2 +- src/journal/journal-send.c | 18 +++--- src/journal/journald-console.c | 9 ++- src/journal/journald-kmsg.c | 9 ++- src/journal/journald-server.c | 2 - src/journal/journald-stream.c | 4 +- src/journal/journald-syslog.c | 9 ++- src/journal/sd-journal.c | 3 +- src/libsystemd-terminal/subterm.c | 8 +-- src/libsystemd/sd-bus/bus-control.c | 6 +- src/libsystemd/sd-bus/bus-socket.c | 8 +-- src/shared/log.c | 26 +++----- src/shared/spawn-polkit-agent.c | 5 +- src/shared/switch-root.c | 1 - src/shared/util.h | 2 + src/timedate/timedatectl.c | 67 +++++++++------------ 23 files changed, 91 insertions(+), 132 deletions(-) diff --git a/src/core/automount.c b/src/core/automount.c index d47e6fa8d..9f6bd84b2 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -449,7 +449,9 @@ int automount_send_ready(Automount *a, int status) { static void automount_enter_waiting(Automount *a) { _cleanup_close_ int ioctl_fd = -1; int p[2] = { -1, -1 }; - char name[32], options[128]; + char name[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t) + 1]; + char options[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1 + + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1]; bool mounted = false; int r, dev_autofs_fd; struct stat st; @@ -477,12 +479,8 @@ static void automount_enter_waiting(Automount *a) { goto fail; } - snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp()); - char_array_0(options); - - snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid()); - char_array_0(name); - + xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp()); + xsprintf(name, "systemd-"PID_FMT, getpid()); if (mount(name, a->where, "autofs", 0, options) < 0) { r = -errno; goto fail; diff --git a/src/core/job.c b/src/core/job.c index 2129773ed..4740ff18c 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -764,7 +764,6 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) { DISABLE_WARNING_FORMAT_NONLITERAL; snprintf(buf, sizeof(buf), format, unit_description(u)); - char_array_0(buf); REENABLE_WARNING; if (t == JOB_START) { diff --git a/src/core/main.c b/src/core/main.c index 0df1f6423..02b7c37f8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1883,7 +1883,7 @@ finish: args = newa(const char*, args_size); if (!switch_root_init) { - char sfd[16]; + char sfd[DECIMAL_STR_MAX(int) + 1]; /* First try to spawn ourselves with the right * path, and with full serialization. We do @@ -1893,8 +1893,7 @@ finish: assert(arg_serialization); assert(fds); - snprintf(sfd, sizeof(sfd), "%i", fileno(arg_serialization)); - char_array_0(sfd); + xsprintf(sfd, "%i", fileno(arg_serialization)); i = 0; args[i++] = SYSTEMD_BINARY_PATH; @@ -1995,7 +1994,7 @@ finish: assert(command_line[pos] == NULL); env_block = strv_copy(environ); - snprintf(log_level, sizeof(log_level), "%d", log_get_max_level()); + xsprintf(log_level, "%d", log_get_max_level()); switch (log_get_target()) { case LOG_TARGET_KMSG: diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index f6389584f..18888747f 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -64,16 +64,16 @@ static int audit_callback( const struct audit_info *audit = auditdata; uid_t uid = 0, login_uid = 0; gid_t gid = 0; - char login_uid_buf[DECIMAL_STR_MAX(uid_t)] = "n/a"; - char uid_buf[DECIMAL_STR_MAX(uid_t)] = "n/a"; - char gid_buf[DECIMAL_STR_MAX(gid_t)] = "n/a"; + char login_uid_buf[DECIMAL_STR_MAX(uid_t) + 1] = "n/a"; + char uid_buf[DECIMAL_STR_MAX(uid_t) + 1] = "n/a"; + char gid_buf[DECIMAL_STR_MAX(gid_t) + 1] = "n/a"; if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0) - snprintf(login_uid_buf, sizeof(login_uid_buf), UID_FMT, login_uid); + xsprintf(login_uid_buf, UID_FMT, login_uid); if (sd_bus_creds_get_euid(audit->creds, &uid) >= 0) - snprintf(uid_buf, sizeof(uid_buf), UID_FMT, uid); + xsprintf(uid_buf, UID_FMT, uid); if (sd_bus_creds_get_egid(audit->creds, &gid) >= 0) - snprintf(gid_buf, sizeof(gid_buf), GID_FMT, gid); + xsprintf(gid_buf, GID_FMT, gid); snprintf(msgbuf, msgbufsize, "auid=%s uid=%s gid=%s%s%s%s%s%s%s", @@ -81,8 +81,6 @@ static int audit_callback( audit->path ? " path=\"" : "", strempty(audit->path), audit->path ? "\"" : "", audit->cmdline ? " cmdline=\"" : "", strempty(audit->cmdline), audit->cmdline ? "\"" : ""); - msgbuf[msgbufsize-1] = 0; - return 0; } diff --git a/src/core/unit.c b/src/core/unit.c index 23ad7c10e..c3433b2c5 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1399,7 +1399,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { DISABLE_WARNING_FORMAT_NONLITERAL; snprintf(buf, sizeof(buf), format, unit_description(u)); - char_array_0(buf); REENABLE_WARNING; mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING : diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 20b794094..78ceeb6fa 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -222,7 +222,7 @@ int main(int argc, char *argv[]) { const char *device, *type; bool root_directory; int progress_pipe[2] = { -1, -1 }; - char dash_c[2+10+1]; + char dash_c[sizeof("-C")-1 + DECIMAL_STR_MAX(int) + 1]; struct stat st; if (argc > 2) { @@ -336,8 +336,7 @@ int main(int argc, char *argv[]) { cmdline[i++] = "-f"; if (progress_pipe[1] >= 0) { - snprintf(dash_c, sizeof(dash_c), "-C%i", progress_pipe[1]); - char_array_0(dash_c); + xsprintf(dash_c, "-C%i", progress_pipe[1]); cmdline[i++] = dash_c; } diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 244d83d36..f1c409cd9 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -406,7 +406,7 @@ static int add_source(RemoteServer *s, int fd, char* name, bool own_name) { static int add_raw_socket(RemoteServer *s, int fd) { int r; _cleanup_close_ int fd_ = fd; - char name[strlen("raw-socket-") + DECIMAL_STR_MAX(int)]; + char name[sizeof("raw-socket-")-1 + DECIMAL_STR_MAX(int) + 1]; assert(fd >= 0); @@ -416,7 +416,7 @@ static int add_raw_socket(RemoteServer *s, int fd) { if (r < 0) return r; - snprintf(name, sizeof(name), "raw-socket-%d", fd); + xsprintf(name, "raw-socket-%d", fd); r = sd_event_source_set_description(s->listen_event, name); if (r < 0) diff --git a/src/journal-remote/journal-upload-journal.c b/src/journal-remote/journal-upload-journal.c index 942320cbf..5fd639a76 100644 --- a/src/journal-remote/journal-upload-journal.c +++ b/src/journal-remote/journal-upload-journal.c @@ -104,7 +104,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) { r = snprintf(buf + pos, size - pos, "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid)); - if (r + pos> size) + if (r + pos > size) /* not enough space */ return pos; diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index 65fefd25a..1e3a46350 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -90,18 +90,17 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) { /* FIXME: Instead of limiting things to LINE_MAX we could do a C99 variable-length array on the stack here in a loop. */ - char buffer[8 + LINE_MAX], p[11]; struct iovec iov[2]; + char buffer[8 + LINE_MAX], p[sizeof("PRIORITY=")-1 + DECIMAL_STR_MAX(int) + 1]; + struct iovec iov[2]; assert_return(priority >= 0, -EINVAL); assert_return(priority <= 7, -EINVAL); assert_return(format, -EINVAL); - snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK); - char_array_0(p); + xsprintf(p, "PRIORITY=%i", priority & LOG_PRIMASK); memcpy(buffer, "MESSAGE=", 8); vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap); - char_array_0(buffer); zero(iov); IOVEC_SET_STRING(iov[0], buffer); @@ -372,7 +371,7 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove errno = 0; j = strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k); if (errno == 0) { - char error[6 + 10 + 1]; /* for a 32bit value */ + char error[sizeof("ERRNO=")-1 + DECIMAL_STR_MAX(int) + 1]; if (j != buffer + 8 + k) memmove(buffer + 8 + k, j, strlen(j)+1); @@ -384,8 +383,7 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove memcpy(buffer + 8 + k - 2, ": ", 2); } - snprintf(error, sizeof(error), "ERRNO=%i", _saved_errno_); - char_array_0(error); + xsprintf(error, "ERRNO=%i", _saved_errno_); IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3"); IOVEC_SET_STRING(iov[skip+1], buffer); @@ -474,7 +472,7 @@ _public_ int sd_journal_print_with_location(int priority, const char *file, cons } _public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) { - char buffer[8 + LINE_MAX], p[11]; + char buffer[8 + LINE_MAX], p[sizeof("PRIORITY=")-1 + DECIMAL_STR_MAX(int) + 1]; struct iovec iov[5]; char *f; @@ -482,12 +480,10 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con assert_return(priority <= 7, -EINVAL); assert_return(format, -EINVAL); - snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK); - char_array_0(p); + xsprintf(p, "PRIORITY=%i", priority & LOG_PRIMASK); memcpy(buffer, "MESSAGE=", 8); vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap); - char_array_0(buffer); /* func is initialized from __func__ which is not a macro, but * a static const char[], hence cannot easily be prefixed with diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c index 4afa6ef9c..5363aaa4f 100644 --- a/src/journal/journald-console.c +++ b/src/journal/journald-console.c @@ -51,9 +51,9 @@ void server_forward_console( const struct ucred *ucred) { struct iovec iovec[5]; - char header_pid[16]; struct timespec ts; - char tbuf[4 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1]; + char tbuf[sizeof("[] ")-1 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1]; + char header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t)]; int n = 0, fd; _cleanup_free_ char *ident_buf = NULL; const char *tty; @@ -67,7 +67,7 @@ void server_forward_console( /* First: timestamp */ if (prefix_timestamp()) { assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); - snprintf(tbuf, sizeof(tbuf), "[%5"PRI_TIME".%06ld] ", + xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ", ts.tv_sec, ts.tv_nsec / 1000); IOVEC_SET_STRING(iovec[n++], tbuf); @@ -80,8 +80,7 @@ void server_forward_console( identifier = ident_buf; } - snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", ucred->pid); - char_array_0(header_pid); + xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid); if (identifier) IOVEC_SET_STRING(iovec[n++], identifier); diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c index aca4571ec..0b02eff6e 100644 --- a/src/journal/journald-kmsg.c +++ b/src/journal/journald-kmsg.c @@ -40,7 +40,8 @@ void server_forward_kmsg( const struct ucred *ucred) { struct iovec iovec[5]; - char header_priority[6], header_pid[16]; + char header_priority[4], + header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t) + 1]; int n = 0; char *ident_buf = NULL; @@ -60,8 +61,7 @@ void server_forward_kmsg( priority = syslog_fixup_facility(priority); /* First: priority field */ - snprintf(header_priority, sizeof(header_priority), "<%i>", priority); - char_array_0(header_priority); + xsprintf(header_priority, "<%i>", priority); IOVEC_SET_STRING(iovec[n++], header_priority); /* Second: identifier and PID */ @@ -71,8 +71,7 @@ void server_forward_kmsg( identifier = ident_buf; } - snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", ucred->pid); - char_array_0(header_pid); + xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid); if (identifier) IOVEC_SET_STRING(iovec[n++], identifier); diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 87b459b3c..aecf8596d 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -837,12 +837,10 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, va_start(ap, format); vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap); va_end(ap); - char_array_0(buffer); IOVEC_SET_STRING(iovec[n++], buffer); if (!sd_id128_equal(message_id, SD_ID128_NULL)) { snprintf(mid, sizeof(mid), LOG_MESSAGE_ID(message_id)); - char_array_0(mid); IOVEC_SET_STRING(iovec[n++], mid); } diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index eabe019bf..942a85780 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -223,7 +223,7 @@ static int stdout_stream_log(StdoutStream *s, const char *p) { struct iovec iovec[N_IOVEC_META_FIELDS + 5]; int priority; char syslog_priority[] = "PRIORITY=\0"; - char syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(priority)]; + char syslog_facility[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1]; _cleanup_free_ char *message = NULL, *syslog_identifier = NULL; unsigned n = 0; char *label = NULL; @@ -258,7 +258,7 @@ static int stdout_stream_log(StdoutStream *s, const char *p) { IOVEC_SET_STRING(iovec[n++], syslog_priority); if (priority & LOG_FACMASK) { - snprintf(syslog_facility, sizeof(syslog_facility), "SYSLOG_FACILITY=%i", LOG_FAC(priority)); + xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)); IOVEC_SET_STRING(iovec[n++], syslog_facility); } diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index 21bc9679c..ba6e3316d 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -124,7 +124,8 @@ static void forward_syslog_raw(Server *s, int priority, const char *buffer, cons void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred, const struct timeval *tv) { struct iovec iovec[5]; - char header_priority[6], header_time[64], header_pid[16]; + char header_priority[4], header_time[64], + header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t) + 1]; int n = 0; time_t t; struct tm *tm; @@ -139,8 +140,7 @@ void server_forward_syslog(Server *s, int priority, const char *identifier, cons return; /* First: priority field */ - snprintf(header_priority, sizeof(header_priority), "<%i>", priority); - char_array_0(header_priority); + xsprintf(header_priority, "<%i>", priority); IOVEC_SET_STRING(iovec[n++], header_priority); /* Second: timestamp */ @@ -159,8 +159,7 @@ void server_forward_syslog(Server *s, int priority, const char *identifier, cons identifier = ident_buf; } - snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", ucred->pid); - char_array_0(header_pid); + xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid); if (identifier) IOVEC_SET_STRING(iovec[n++], identifier); diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 9bc426faf..9dea5470b 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1178,8 +1178,7 @@ static bool file_type_wanted(int flags, const char *filename) { if (flags & SD_JOURNAL_CURRENT_USER) { char prefix[5 + DECIMAL_STR_MAX(uid_t) + 1]; - assert_se(snprintf(prefix, sizeof(prefix), "user-"UID_FMT, getuid()) - < (int) sizeof(prefix)); + xsprintf(prefix, "user-"UID_FMT, getuid()); if (file_has_type_prefix(prefix, filename)) return true; diff --git a/src/libsystemd-terminal/subterm.c b/src/libsystemd-terminal/subterm.c index 7c119ac58..63cd2a5ad 100644 --- a/src/libsystemd-terminal/subterm.c +++ b/src/libsystemd-terminal/subterm.c @@ -161,16 +161,14 @@ static int output_write(Output *o, const void *buf, size_t size) { _printf_(3,0) static int output_vnprintf(Output *o, size_t max, const char *format, va_list args) { - char buf[4096]; + char buf[max]; int r; assert_return(o, -EINVAL); assert_return(format, -EINVAL); - assert_return(max <= sizeof(buf), -EINVAL); + assert_return(max <= 4096, -EINVAL); - r = vsnprintf(buf, max, format, args); - if (r > (ssize_t)max) - r = max; + r = MIN(vsnprintf(buf, max, format, args), (int) max); return output_write(o, buf, r); } diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index babfed8c2..8d12c258f 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -1268,7 +1268,7 @@ int bus_add_match_internal_kernel( if (c->type - BUS_MATCH_ARG < 3) name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str; - snprintf(buf, sizeof(buf), "arg%i", c->type - BUS_MATCH_ARG); + xsprintf(buf, "arg%i", c->type - BUS_MATCH_ARG); bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str); using_bloom = true; break; @@ -1277,7 +1277,7 @@ int bus_add_match_internal_kernel( case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: { char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")]; - snprintf(buf, sizeof(buf), "arg%i-slash-prefix", c->type - BUS_MATCH_ARG_PATH); + xsprintf(buf, "arg%i-slash-prefix", c->type - BUS_MATCH_ARG_PATH); bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str); using_bloom = true; break; @@ -1286,7 +1286,7 @@ int bus_add_match_internal_kernel( case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: { char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")]; - snprintf(buf, sizeof(buf), "arg%i-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE); + xsprintf(buf, "arg%i-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE); bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str); using_bloom = true; break; diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index d02994e28..d3eb83481 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -359,8 +359,7 @@ static int bus_socket_auth_write_ok(sd_bus *b) { assert(b); - snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id)); - char_array_0(t); + xsprintf(t, "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id)); return bus_socket_auth_write(b, t); } @@ -644,12 +643,11 @@ static int bus_socket_start_auth_client(sd_bus *b) { l = 9; b->auth_buffer = hexmem("anonymous", l); } else { - char text[20 + 1]; /* enough space for a 64bit integer plus NUL */ + char text[DECIMAL_STR_MAX(uid_t) + 1]; auth_prefix = "\0AUTH EXTERNAL "; - snprintf(text, sizeof(text), UID_FMT, geteuid()); - char_array_0(text); + xsprintf(text, UID_FMT, geteuid()); l = strlen(text); b->auth_buffer = hexmem(text, l); diff --git a/src/shared/log.c b/src/shared/log.c index a870415a0..9c0156026 100644 --- a/src/shared/log.c +++ b/src/shared/log.c @@ -331,7 +331,6 @@ static int write_to_console( if (show_location) { snprintf(location, sizeof(location), "(%s:%i) ", file, line); - char_array_0(location); IOVEC_SET_STRING(iovec[n++], location); } @@ -375,7 +374,9 @@ static int write_to_syslog( const char *object, const char *buffer) { - char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_time[64], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4]; + char header_priority[2 + DECIMAL_STR_MAX(int) + 1], + header_time[64], + header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1]; struct iovec iovec[5] = {}; struct msghdr msghdr = { .msg_iov = iovec, @@ -387,8 +388,7 @@ static int write_to_syslog( if (syslog_fd < 0) return 0; - snprintf(header_priority, sizeof(header_priority), "<%i>", level); - char_array_0(header_priority); + xsprintf(header_priority, "<%i>", level); t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC); tm = localtime(&t); @@ -398,8 +398,7 @@ static int write_to_syslog( if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0) return -EINVAL; - snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid()); - char_array_0(header_pid); + xsprintf(header_pid, "["PID_FMT"]: ", getpid()); IOVEC_SET_STRING(iovec[0], header_priority); IOVEC_SET_STRING(iovec[1], header_time); @@ -438,17 +437,15 @@ static int write_to_kmsg( const char *object, const char *buffer) { - char header_priority[1 + DECIMAL_STR_MAX(int) + 2], header_pid[1 + DECIMAL_STR_MAX(pid_t) + 4]; + char header_priority[2 + DECIMAL_STR_MAX(int) + 1], + header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1]; struct iovec iovec[5] = {}; if (kmsg_fd < 0) return 0; - snprintf(header_priority, sizeof(header_priority), "<%i>", level); - char_array_0(header_priority); - - snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid()); - char_array_0(header_pid); + xsprintf(header_priority, "<%i>", level); + xsprintf(header_pid, "["PID_FMT"]: ", getpid()); IOVEC_SET_STRING(iovec[0], header_priority); IOVEC_SET_STRING(iovec[1], program_invocation_short_name); @@ -497,7 +494,6 @@ static int log_do_header( isempty(object) ? "" : object, isempty(object) ? "" : "\n", program_invocation_short_name); - header[size - 1] = '\0'; return 0; } @@ -659,7 +655,6 @@ int log_internalv( errno = error; vsnprintf(buffer, sizeof(buffer), format, ap); - char_array_0(buffer); return log_dispatch(level, error, file, line, func, NULL, NULL, buffer); } @@ -707,7 +702,6 @@ int log_object_internalv( errno = error; vsnprintf(buffer, sizeof(buffer), format, ap); - char_array_0(buffer); return log_dispatch(level, error, file, line, func, object_field, object, buffer); } @@ -749,7 +743,6 @@ static void log_assert( snprintf(buffer, sizeof(buffer), format, text, file, line, func); REENABLE_WARNING; - char_array_0(buffer); log_abort_msg = buffer; log_dispatch(level, 0, file, line, func, NULL, NULL, buffer); @@ -875,7 +868,6 @@ int log_struct_internal( va_copy(aq, ap); vsnprintf(buf, sizeof(buf), format, aq); va_end(aq); - char_array_0(buf); if (startswith(buf, "MESSAGE=")) { found = true; diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c index e7419b5ee..006ad532b 100644 --- a/src/shared/spawn-polkit-agent.c +++ b/src/shared/spawn-polkit-agent.c @@ -39,7 +39,7 @@ static pid_t agent_pid = 0; int polkit_agent_open(void) { int r; int pipe_fd[2]; - char notify_fd[10 + 1]; + char notify_fd[DECIMAL_STR_MAX(int) + 1]; if (agent_pid > 0) return 0; @@ -52,8 +52,7 @@ int polkit_agent_open(void) { if (pipe2(pipe_fd, 0) < 0) return -errno; - snprintf(notify_fd, sizeof(notify_fd), "%i", pipe_fd[1]); - char_array_0(notify_fd); + xsprintf(notify_fd, "%i", pipe_fd[1]); r = fork_agent(&agent_pid, &pipe_fd[1], 1, diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c index ca3875628..e8cedc69c 100644 --- a/src/shared/switch-root.c +++ b/src/shared/switch-root.c @@ -72,7 +72,6 @@ int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot, struct stat sb; snprintf(new_mount, sizeof(new_mount), "%s%s", new_root, i); - char_array_0(new_mount); mkdir_p_label(new_mount, 0755); diff --git a/src/shared/util.h b/src/shared/util.h index ca0c2e5e3..531242213 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -481,6 +481,8 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus); int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_(4,0); int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) _printf_(4,5); +#define xsprintf(buf, fmt, ...) assert_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf)) + int fd_columns(int fd); unsigned columns(void); int fd_lines(int fd); diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index 74f40b9c8..1f85536cf 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -38,6 +38,8 @@ #include "pager.h" #include "time-dst.h" +#define xstrftime(buf, fmt, tm) assert_se(strftime(buf, sizeof(buf), fmt, tm) > 0) + static bool arg_no_pager = false; static bool arg_ask_password = true; static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; @@ -123,15 +125,11 @@ static void print_status_info(const StatusInfo *i) { fprintf(stderr, "Warning: Could not get time from timedated and not operating locally.\n\n"); if (have_time) { - zero(tm); - assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) > 0); - char_array_0(a); - printf(" Local time: %s\n", a); - - zero(tm); - assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm)) > 0); - char_array_0(a); - printf(" Universal time: %s\n", a); + xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)); + printf(" Local time: %.*s\n", (int) sizeof(a), a); + + xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm)); + printf(" Universal time: %.*s\n", (int) sizeof(a), a); } else { printf(" Local time: %s\n", "n/a"); printf(" Universal time: %s\n", "n/a"); @@ -141,24 +139,19 @@ static void print_status_info(const StatusInfo *i) { time_t rtc_sec; rtc_sec = (time_t)(i->rtc_time / USEC_PER_SEC); - zero(tm); - assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm)) > 0); - char_array_0(a); - printf(" RTC time: %s\n", a); + xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm)); + printf(" RTC time: %.*s\n", (int) sizeof(a), a); } else printf(" RTC time: %s\n", "n/a"); - if (have_time) { - zero(tm); - assert_se(strftime(a, sizeof(a), "%Z, %z", localtime_r(&sec, &tm)) > 0); - char_array_0(a); - } + if (have_time) + xstrftime(a, "%Z, %z", localtime_r(&sec, &tm)); - printf(" Time zone: %s (%s)\n" + printf(" Time zone: %s (%.*s)\n" " NTP enabled: %s\n" "NTP synchronized: %s\n" " RTC in local TZ: %s\n", - strna(i->timezone), have_time ? a : "n/a", + strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a", i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a", yes_no(i->ntp_synced), yes_no(i->rtc_local)); @@ -173,30 +166,26 @@ static void print_status_info(const StatusInfo *i) { printf(" DST active: %s\n", yes_no(is_dstc)); t = tc - 1; - zero(tm); - assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0); - char_array_0(a); + xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)); - zero(tm); - assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0); - char_array_0(b); + xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)); printf(" Last DST change: DST %s at\n" - " %s\n" - " %s\n", - is_dstc ? "began" : "ended", a, b); + " %.*s\n" + " %.*s\n", + is_dstc ? "began" : "ended", + (int) sizeof(a), a, + (int) sizeof(b), b); t = tn - 1; - zero(tm); - assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0); - char_array_0(a); - - zero(tm); - assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0); - char_array_0(b); + xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)); + xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)); printf(" Next DST change: DST %s (the clock jumps %s) at\n" - " %s\n" - " %s\n", - is_dstn ? "begins" : "ends", jump_str(dn, s, sizeof(s)), a, b); + " %.*s\n" + " %.*s\n", + is_dstn ? "begins" : "ends", + jump_str(dn, s, sizeof(s)), + (int) sizeof(a), a, + (int) sizeof(b), b); } } else printf(" DST active: %s\n", yes_no(is_dstc)); -- 2.30.2