chiark / gitweb /
Add a snprinf wrapper which checks that the buffer was big enough
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 27 Jan 2015 13:00:11 +0000 (08:00 -0500)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 1 Feb 2015 22:21:39 +0000 (17:21 -0500)
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.

23 files changed:
src/core/automount.c
src/core/job.c
src/core/main.c
src/core/selinux-access.c
src/core/unit.c
src/fsck/fsck.c
src/journal-remote/journal-remote.c
src/journal-remote/journal-upload-journal.c
src/journal/journal-send.c
src/journal/journald-console.c
src/journal/journald-kmsg.c
src/journal/journald-server.c
src/journal/journald-stream.c
src/journal/journald-syslog.c
src/journal/sd-journal.c
src/libsystemd-terminal/subterm.c
src/libsystemd/sd-bus/bus-control.c
src/libsystemd/sd-bus/bus-socket.c
src/shared/log.c
src/shared/spawn-polkit-agent.c
src/shared/switch-root.c
src/shared/util.h
src/timedate/timedatectl.c

index d47e6fa..9f6bd84 100644 (file)
@@ -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;
index 2129773..4740ff1 100644 (file)
@@ -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) {
index 0df1f64..02b7c37 100644 (file)
@@ -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:
index f638958..1888874 100644 (file)
@@ -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;
 }
 
index 23ad7c1..c3433b2 100644 (file)
@@ -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 :
index 20b7940..78ceeb6 100644 (file)
@@ -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;
         }
 
index 244d83d..f1c409c 100644 (file)
@@ -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)
index 942320c..5fd639a 100644 (file)
@@ -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;
 
index 65fefd2..1e3a463 100644 (file)
@@ -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
index 4afa6ef..5363aaa 100644 (file)
@@ -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);
index aca4571..0b02eff 100644 (file)
@@ -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);
index 87b459b..aecf859 100644 (file)
@@ -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);
         }
 
index eabe019..942a857 100644 (file)
@@ -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);
         }
 
index 21bc967..ba6e331 100644 (file)
@@ -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);
index 9bc426f..9dea547 100644 (file)
@@ -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;
index 7c119ac..63cd2a5 100644 (file)
@@ -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);
 }
index babfed8..8d12c25 100644 (file)
@@ -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;
index d02994e..d3eb834 100644 (file)
@@ -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);
index a870415..9c01560 100644 (file)
@@ -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;
index e7419b5..006ad53 100644 (file)
@@ -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,
index ca38756..e8cedc6 100644 (file)
@@ -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);
 
index ca0c2e5..5312422 100644 (file)
@@ -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);
index 74f40b9..1f85536 100644 (file)
@@ -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));